[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