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

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