Blame SOURCES/0004-Xi-disallow-passive-grabs-with-a-detail-255.patch

fa07e0
From 0dab0b527ac5c4fe0272ea679522bd87238a733b Mon Sep 17 00:00:00 2001
fa07e0
From: Peter Hutterer <peter.hutterer@who-t.net>
fa07e0
Date: Tue, 29 Nov 2022 13:55:32 +1000
fa07e0
Subject: [PATCH xserver 4/7] Xi: disallow passive grabs with a detail > 255
fa07e0
fa07e0
The XKB protocol effectively prevents us from ever using keycodes above
fa07e0
255. For buttons it's theoretically possible but realistically too niche
fa07e0
to worry about. For all other passive grabs, the detail must be zero
fa07e0
anyway.
fa07e0
fa07e0
This fixes an OOB write:
fa07e0
fa07e0
ProcXIPassiveUngrabDevice() calls DeletePassiveGrabFromList with a
fa07e0
temporary grab struct which contains tempGrab->detail.exact = stuff->detail.
fa07e0
For matching existing grabs, DeleteDetailFromMask is called with the
fa07e0
stuff->detail value. This function creates a new mask with the one bit
fa07e0
representing stuff->detail cleared.
fa07e0
fa07e0
However, the array size for the new mask is 8 * sizeof(CARD32) bits,
fa07e0
thus any detail above 255 results in an OOB array write.
fa07e0
fa07e0
CVE-2022-46341, ZDI-CAN 19381
fa07e0
fa07e0
This vulnerability was discovered by:
fa07e0
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
fa07e0
fa07e0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
fa07e0
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
fa07e0
---
fa07e0
 Xi/xipassivegrab.c | 22 ++++++++++++++--------
fa07e0
 1 file changed, 14 insertions(+), 8 deletions(-)
fa07e0
fa07e0
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
fa07e0
index 2769fb7c94..c9ac2f8553 100644
fa07e0
--- a/Xi/xipassivegrab.c
fa07e0
+++ b/Xi/xipassivegrab.c
fa07e0
@@ -137,6 +137,12 @@ ProcXIPassiveGrabDevice(ClientPtr client)
fa07e0
         return BadValue;
fa07e0
     }
fa07e0
 
fa07e0
+    /* XI2 allows 32-bit keycodes but thanks to XKB we can never
fa07e0
+     * implement this. Just return an error for all keycodes that
fa07e0
+     * cannot work anyway, same for buttons > 255. */
fa07e0
+    if (stuff->detail > 255)
fa07e0
+        return XIAlreadyGrabbed;
fa07e0
+
fa07e0
     if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
fa07e0
                                stuff->mask_len * 4) != Success)
fa07e0
         return BadValue;
fa07e0
@@ -207,14 +213,8 @@ ProcXIPassiveGrabDevice(ClientPtr client)
fa07e0
                                 &param, XI2, &mask);
fa07e0
             break;
fa07e0
         case XIGrabtypeKeycode:
fa07e0
-            /* XI2 allows 32-bit keycodes but thanks to XKB we can never
fa07e0
-             * implement this. Just return an error for all keycodes that
fa07e0
-             * cannot work anyway */
fa07e0
-            if (stuff->detail > 255)
fa07e0
-                status = XIAlreadyGrabbed;
fa07e0
-            else
fa07e0
-                status = GrabKey(client, dev, mod_dev, stuff->detail,
fa07e0
-                                 &param, XI2, &mask);
fa07e0
+            status = GrabKey(client, dev, mod_dev, stuff->detail,
fa07e0
+                             &param, XI2, &mask);
fa07e0
             break;
fa07e0
         case XIGrabtypeEnter:
fa07e0
         case XIGrabtypeFocusIn:
fa07e0
@@ -334,6 +334,12 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
fa07e0
         return BadValue;
fa07e0
     }
fa07e0
 
fa07e0
+    /* We don't allow passive grabs for details > 255 anyway */
fa07e0
+    if (stuff->detail > 255) {
fa07e0
+        client->errorValue = stuff->detail;
fa07e0
+        return BadValue;
fa07e0
+    }
fa07e0
+
fa07e0
     rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
fa07e0
     if (rc != Success)
fa07e0
         return rc;
fa07e0
-- 
fa07e0
2.38.1
fa07e0