[PATCH synaptics] Fix stack smash in clickpad_guess_clickfingers()

Benjamin Tissoires benjamin.tissoires at gmail.com
Thu Apr 25 09:35:20 PDT 2013


From: Benjamin Tissoires <benjamin.tissoires at redhat.com>

Apple Magic Trackpad can report 16 slots. In clickpad_guess_clickfingers()
the array allocated on the stack contains only 10 slots.
As (.num_mt_mask == .num_slots), the function writes out of the bounds
of close_point.

Dynamically allocating the buffer depending on the effective num_slots
is safer.

This fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=952221

Signed-off-by: Benjamin Tissoires <benjamin.tissoires at redhat.com>
---

Hi,

I know this is not the ideal patch, but it solves the problem.
Any better idea ( besides bumping SYNAPTICS_MAX_TOUCHES to 20 ) is welcome :)

Cheers,
Benjamin

 src/synaptics.c    | 18 ++++++++++++++----
 src/synapticsstr.h |  1 +
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/synaptics.c b/src/synaptics.c
index f0a8269..eadf93b 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -880,6 +880,8 @@ SynapticsUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
         valuator_mask_free(&priv->scroll_events_mask);
     if (priv && priv->open_slots)
         free(priv->open_slots);
+    if (priv && priv->close_point)
+        free(priv->close_point);
     free(pInfo->private);
     pInfo->private = NULL;
     xf86DeleteInput(pInfo, 0);
@@ -1101,12 +1103,16 @@ DeviceInitTouch(DeviceIntPtr dev, Atom *axes_labels)
         priv->num_slots =
             priv->max_touches ? priv->max_touches : SYNAPTICS_MAX_TOUCHES;
 
+        priv->close_point = malloc(priv->num_slots * sizeof(char));/* 1 for each point close
+                                                                      to another one */
         priv->open_slots = malloc(priv->num_slots * sizeof(int));
-        if (!priv->open_slots) {
+        if (!priv->open_slots || !priv->close_point) {
             xf86IDrvMsg(pInfo, X_ERROR,
                         "failed to allocate open touch slots array\n");
             priv->has_touch = 0;
             priv->num_slots = 0;
+            free(priv->open_slots);
+            free(priv->close_point);
             return;
         }
 
@@ -1119,6 +1125,7 @@ DeviceInitTouch(DeviceIntPtr dev, Atom *axes_labels)
             priv->has_touch = 0;
             priv->num_slots = 0;
             free(priv->open_slots);
+            free(priv->close_point);
             priv->open_slots = NULL;
             return;
         }
@@ -1298,6 +1305,7 @@ DeviceInit(DeviceIntPtr dev)
     free(priv->local_hw_state);
     free(priv->hwState);
     free(priv->open_slots);
+    free(priv->close_point);
     return !Success;
 }
 
@@ -2453,10 +2461,12 @@ clickpad_guess_clickfingers(SynapticsPrivate * priv,
                             struct SynapticsHwState *hw)
 {
     int nfingers = 0;
-    char close_point[SYNAPTICS_MAX_TOUCHES] = { 0 };    /* 1 for each point close
-                                                           to another one */
+
+    char *close_point = priv->close_point;
     int i, j;
 
+    memset(close_point, 0, priv->num_slots * sizeof(char));
+
     for (i = 0; i < hw->num_mt_mask - 1; i++) {
         ValuatorMask *f1;
 
@@ -2494,7 +2504,7 @@ clickpad_guess_clickfingers(SynapticsPrivate * priv,
         }
     }
 
-    for (i = 0; i < SYNAPTICS_MAX_TOUCHES; i++)
+    for (i = 0; i < priv->num_slots; i++)
         nfingers += close_point[i];
 
     return nfingers;
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 428befa..68320ed 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -281,6 +281,7 @@ struct _SynapticsPrivateRec {
     int num_slots;              /* Number of touch slots allocated */
     int *open_slots;            /* Array of currently open touch slots */
     int num_active_touches;     /* Number of active touches on device */
+    char *close_point;          /* Buffer required by clickpad_guess_clickfingers() */
 };
 
 #endif                          /* _SYNAPTICSSTR_H_ */
-- 
1.8.1.4



More information about the xorg-devel mailing list