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