dix: limit checks to MAX_VALUATORS when generating Xi events

Previously, it was looping through sizeof(ev->valuators.mask) * 8
valuators, where valuators.mask is defined as an array of
(MAX_VALUATORS + 7) / 8 entries.  Since MAX_VALUATORS is defined as 36,
this made it actually loop through 40 entries.  The last 4 bits in this
array should never be set, so we should never access memory outside the
bounds of the arrays defined to be exactly MAX_VALUATORS in length, but
we can make the static analyzer happier and not waste time checking bits
that should never be set.

Found by Oracle Parfait 13.3 static analyzer:

   Read outside array bounds [read-outside-array-bounds]:
      In array dereference of ev->valuators.data[i] with index i
      Array size is 36 elements (of 8 bytes each), index >= 0 and index <= 39
        at line 741 of dix/eventconvert.c in function 'eventToDeviceEvent'.

   Read outside array bounds [read-outside-array-bounds]:
      In array dereference of ev->valuators.data[i] with index i
      Array size is 36 elements (of 8 bytes each), index >= 0 and index <= 39
        at line 808 of dix/eventconvert.c in function 'eventToRawEvent'.

   Read outside array bounds [read-outside-array-bounds]:
      In array dereference of ev->valuators.data_raw[i] with index i
      Array size is 36 elements (of 8 bytes each), index >= 0 and index <= 39
        at line 809 of dix/eventconvert.c in function 'eventToRawEvent'.

Fixes: b2ba77bac ("dix: add EventToXI2 and GetXI2Type.")
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1730>
This commit is contained in:
Alan Coopersmith 2024-10-12 17:33:24 -07:00 committed by Marge Bot
parent 4b073d65bb
commit b65eea43dd

View File

@ -735,7 +735,7 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
ptr += xde->buttons_len * 4; ptr += xde->buttons_len * 4;
axisval = (FP3232 *) (ptr + xde->valuators_len * 4); axisval = (FP3232 *) (ptr + xde->valuators_len * 4);
for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) { for (i = 0; i < MAX_VALUATORS; i++) {
if (BitIsOn(ev->valuators.mask, i)) { if (BitIsOn(ev->valuators.mask, i)) {
SetBit(ptr, i); SetBit(ptr, i);
*axisval = double_to_fp3232(ev->valuators.data[i]); *axisval = double_to_fp3232(ev->valuators.data[i]);
@ -802,7 +802,7 @@ eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
ptr = (char *) &raw[1]; ptr = (char *) &raw[1];
axisval = (FP3232 *) (ptr + raw->valuators_len * 4); axisval = (FP3232 *) (ptr + raw->valuators_len * 4);
axisval_raw = axisval + nvals; axisval_raw = axisval + nvals;
for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) { for (i = 0; i < MAX_VALUATORS; i++) {
if (BitIsOn(ev->valuators.mask, i)) { if (BitIsOn(ev->valuators.mask, i)) {
SetBit(ptr, i); SetBit(ptr, i);
*axisval = double_to_fp3232(ev->valuators.data[i]); *axisval = double_to_fp3232(ev->valuators.data[i]);