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

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