From: Peter Hutterer Date: Thu, 5 Mar 2020 03:37:46 +0000 (+1000) Subject: Don't overrun the changes array when synching > MAX_SLOTS X-Git-Tag: libevdev-1.9.1~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=87a91718ef8883d0911900626a2529720c61bbef;p=platform%2Fupstream%2Flibevdev.git 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 --- diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c index f034637..f7543e0 100644 --- a/libevdev/libevdev.c +++ b/libevdev/libevdev.c @@ -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; }