Don't overrun the changes array when synching > MAX_SLOTS

On a device with more than 256 slots we would read (and copy) past our changes
stack-allocated changes array. Fix this by capping to MAX_SLOTS though this
also requires us to memset the target where it is larger than MAX_SLOTS.

There are no real devices with 256+ slots, so this is a theoretical issue
only.

Fixes #11

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2020-03-05 13:37:46 +10:00
parent 103f3870f0
commit 87a91718ef

View file

@ -680,6 +680,7 @@ sync_mt_state(struct libevdev *dev,
#define MAX_SLOTS 256
int rc = 0;
struct slot_change_state changes[MAX_SLOTS] = {0};
unsigned int nslots = min(MAX_SLOTS, dev->num_slots);
for (int axis = ABS_MT_MIN; axis <= ABS_MT_MAX; axis++) {
/* EVIOCGMTSLOTS required format */
@ -697,7 +698,7 @@ sync_mt_state(struct libevdev *dev,
if (rc < 0)
goto out;
for (int slot = 0; slot < min(MAX_SLOTS, dev->num_slots); slot++) {
for (unsigned int slot = 0; slot < nslots; slot++) {
int val_before = *slot_value(dev, slot, axis),
val_after = mt_state.val[slot];
@ -728,7 +729,10 @@ sync_mt_state(struct libevdev *dev,
}
}
memcpy(changes_out, changes, sizeof(*changes) * dev->num_slots);
if (dev->num_slots > MAX_SLOTS)
memset(changes_out, 0, sizeof(*changes) * dev->num_slots);
memcpy(changes_out, changes, sizeof(*changes) * nslots);
out:
return rc;
}