Blame SOURCES/0002-dix-Allocate-sufficient-xEvents-for-our-DeviceStateN.patch

f4a46c
From ece23be888a93b741aa1209d1dbf64636109d6a5 Mon Sep 17 00:00:00 2001
f4a46c
From: Peter Hutterer <peter.hutterer@who-t.net>
f4a46c
Date: Mon, 18 Dec 2023 14:27:50 +1000
f4a46c
Subject: [PATCH 2/9] dix: Allocate sufficient xEvents for our
f4a46c
 DeviceStateNotify
f4a46c
f4a46c
If a device has both a button class and a key class and numButtons is
f4a46c
zero, we can get an OOB write due to event under-allocation.
f4a46c
f4a46c
This function seems to assume a device has either keys or buttons, not
f4a46c
both. It has two virtually identical code paths, both of which assume
f4a46c
they're applying to the first event in the sequence.
f4a46c
f4a46c
A device with both a key and button class triggered a logic bug - only
f4a46c
one xEvent was allocated but the deviceStateNotify pointer was pushed on
f4a46c
once per type. So effectively this logic code:
f4a46c
f4a46c
   int count = 1;
f4a46c
   if (button && nbuttons > 32) count++;
f4a46c
   if (key && nbuttons > 0) count++;
f4a46c
   if (key && nkeys > 32) count++; // this is basically always true
f4a46c
   // count is at 2 for our keys + zero button device
f4a46c
f4a46c
   ev = alloc(count * sizeof(xEvent));
f4a46c
   FixDeviceStateNotify(ev);
f4a46c
   if (button)
f4a46c
     FixDeviceStateNotify(ev++);
f4a46c
   if (key)
f4a46c
     FixDeviceStateNotify(ev++);   // santa drops into the wrong chimney here
f4a46c
f4a46c
If the device has more than 3 valuators, the OOB is pushed back - we're
f4a46c
off by one so it will happen when the last deviceValuator event is
f4a46c
written instead.
f4a46c
f4a46c
Fix this by allocating the maximum number of events we may allocate.
f4a46c
Note that the current behavior is not protocol-correct anyway, this
f4a46c
patch fixes only the allocation issue.
f4a46c
f4a46c
Note that this issue does not trigger if the device has at least one
f4a46c
button. While the server does not prevent a button class with zero
f4a46c
buttons, it is very unlikely.
f4a46c
f4a46c
CVE-2024-0229, ZDI-CAN-22678
f4a46c
f4a46c
This vulnerability was discovered by:
f4a46c
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
f4a46c
---
f4a46c
 dix/enterleave.c | 6 +++---
f4a46c
 1 file changed, 3 insertions(+), 3 deletions(-)
f4a46c
f4a46c
diff --git a/dix/enterleave.c b/dix/enterleave.c
f4a46c
index ded8679d7..17964b00a 100644
f4a46c
--- a/dix/enterleave.c
f4a46c
+++ b/dix/enterleave.c
f4a46c
@@ -675,7 +675,8 @@ static void
f4a46c
 DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
f4a46c
 {
f4a46c
     int evcount = 1;
f4a46c
-    deviceStateNotify *ev, *sev;
f4a46c
+    deviceStateNotify sev[6 + (MAX_VALUATORS + 2)/3];
f4a46c
+    deviceStateNotify *ev;
f4a46c
     deviceKeyStateNotify *kev;
f4a46c
     deviceButtonStateNotify *bev;
f4a46c
 
f4a46c
@@ -714,7 +715,7 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
f4a46c
         }
f4a46c
     }
f4a46c
 
f4a46c
-    sev = ev = xallocarray(evcount, sizeof(xEvent));
f4a46c
+    ev = sev;
f4a46c
     FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
f4a46c
 
f4a46c
     if (b != NULL) {
f4a46c
@@ -770,7 +771,6 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
f4a46c
 
f4a46c
     DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
f4a46c
                           DeviceStateNotifyMask, NullGrab);
f4a46c
-    free(sev);
f4a46c
 }
f4a46c
 
f4a46c
 void
f4a46c
-- 
f4a46c
2.43.0
f4a46c