From: Benjamin Tissoires <[email protected]> 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 <[email protected]> --- 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
