1 |
From 0dab0b527ac5c4fe0272ea679522bd87238a733b Mon Sep 17 00:00:00 2001 |
2 |
From: Peter Hutterer <peter.hutterer@who-t.net> |
3 |
Date: Tue, 29 Nov 2022 13:55:32 +1000 |
4 |
Subject: [PATCH xserver 4/7] Xi: disallow passive grabs with a detail > 255 |
5 |
|
6 |
The XKB protocol effectively prevents us from ever using keycodes above |
7 |
255. For buttons it's theoretically possible but realistically too niche |
8 |
to worry about. For all other passive grabs, the detail must be zero |
9 |
anyway. |
10 |
|
11 |
This fixes an OOB write: |
12 |
|
13 |
ProcXIPassiveUngrabDevice() calls DeletePassiveGrabFromList with a |
14 |
temporary grab struct which contains tempGrab->detail.exact = stuff->detail. |
15 |
For matching existing grabs, DeleteDetailFromMask is called with the |
16 |
stuff->detail value. This function creates a new mask with the one bit |
17 |
representing stuff->detail cleared. |
18 |
|
19 |
However, the array size for the new mask is 8 * sizeof(CARD32) bits, |
20 |
thus any detail above 255 results in an OOB array write. |
21 |
|
22 |
CVE-2022-46341, ZDI-CAN 19381 |
23 |
|
24 |
This vulnerability was discovered by: |
25 |
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative |
26 |
|
27 |
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> |
28 |
Acked-by: Olivier Fourdan <ofourdan@redhat.com> |
29 |
--- |
30 |
Xi/xipassivegrab.c | 22 ++++++++++++++-------- |
31 |
1 file changed, 14 insertions(+), 8 deletions(-) |
32 |
|
33 |
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c |
34 |
index 2769fb7c94..c9ac2f8553 100644 |
35 |
--- a/Xi/xipassivegrab.c |
36 |
+++ b/Xi/xipassivegrab.c |
37 |
@@ -137,6 +137,12 @@ ProcXIPassiveGrabDevice(ClientPtr client) |
38 |
return BadValue; |
39 |
} |
40 |
|
41 |
+ /* XI2 allows 32-bit keycodes but thanks to XKB we can never |
42 |
+ * implement this. Just return an error for all keycodes that |
43 |
+ * cannot work anyway, same for buttons > 255. */ |
44 |
+ if (stuff->detail > 255) |
45 |
+ return XIAlreadyGrabbed; |
46 |
+ |
47 |
if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1], |
48 |
stuff->mask_len * 4) != Success) |
49 |
return BadValue; |
50 |
@@ -207,14 +213,8 @@ ProcXIPassiveGrabDevice(ClientPtr client) |
51 |
¶m, XI2, &mask); |
52 |
break; |
53 |
case XIGrabtypeKeycode: |
54 |
- /* XI2 allows 32-bit keycodes but thanks to XKB we can never |
55 |
- * implement this. Just return an error for all keycodes that |
56 |
- * cannot work anyway */ |
57 |
- if (stuff->detail > 255) |
58 |
- status = XIAlreadyGrabbed; |
59 |
- else |
60 |
- status = GrabKey(client, dev, mod_dev, stuff->detail, |
61 |
- ¶m, XI2, &mask); |
62 |
+ status = GrabKey(client, dev, mod_dev, stuff->detail, |
63 |
+ ¶m, XI2, &mask); |
64 |
break; |
65 |
case XIGrabtypeEnter: |
66 |
case XIGrabtypeFocusIn: |
67 |
@@ -334,6 +334,12 @@ ProcXIPassiveUngrabDevice(ClientPtr client) |
68 |
return BadValue; |
69 |
} |
70 |
|
71 |
+ /* We don't allow passive grabs for details > 255 anyway */ |
72 |
+ if (stuff->detail > 255) { |
73 |
+ client->errorValue = stuff->detail; |
74 |
+ return BadValue; |
75 |
+ } |
76 |
+ |
77 |
rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess); |
78 |
if (rc != Success) |
79 |
return rc; |
80 |
-- |
81 |
2.38.1 |
82 |
|