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