diff --git a/debian/changelog b/debian/changelog index 7daa9511547107193aa44529b151c1b5e46ffb61..018f7385270e4189118570b7c3299f20eaca99bb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,22 @@ +xorg-server (2:1.20.11-1+deb11u4) bullseye-security; urgency=high + + * Non-maintainer upload by the Security Team. + * Xtest: disallow GenericEvents in XTestSwapFakeInput (CVE-2022-46340) + (Closes: #1026071) + * Xi: disallow passive grabs with a detail > 255 (CVE-2022-46341) + (Closes: #1026071) + * Xext: free the XvRTVideoNotify when turning off from the same client + (CVE-2022-46342) (Closes: #1026071) + * Xext: free the screen saver resource when replacing it (CVE-2022-46343) + (Closes: #1026071) + * Xi: return an error from XI property changes if verification failed + * Xi: avoid integer truncation in length check of ProcXIChangeProperty + (CVE-2022-46344) (Closes: #1026071) + * xkb: reset the radio_groups pointer to NULL after freeing it + (CVE-2022-4283) (Closes: #1026071) + + -- Salvatore Bonaccorso <carnil@debian.org> Sat, 17 Dec 2022 11:00:08 +0100 + xorg-server (2:1.20.11-1+deb11u3) bullseye-security; urgency=medium * xkb: proof GetCountedString against request length attacks (CVE-2022-3550) diff --git a/debian/patches/13_Xtest-disallow-GenericEvents-in-XTestSwapFakeInput.patch b/debian/patches/13_Xtest-disallow-GenericEvents-in-XTestSwapFakeInput.patch new file mode 100644 index 0000000000000000000000000000000000000000..98c86f41c9aa72d866b4e0a44481ede61857139e --- /dev/null +++ b/debian/patches/13_Xtest-disallow-GenericEvents-in-XTestSwapFakeInput.patch @@ -0,0 +1,54 @@ +From: Peter Hutterer <peter.hutterer@who-t.net> +Date: Tue, 29 Nov 2022 12:55:45 +1000 +Subject: Xtest: disallow GenericEvents in XTestSwapFakeInput +Origin: https://gitlab.freedesktop.org/xorg/xserver/commit/936d34bdff4c479ccd0405fc221ff8e4c6c7014d +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2022-46340 +Bug-Debian: https://bugs.debian.org/1026071 + +XTestSwapFakeInput assumes all events in this request are +sizeof(xEvent) and iterates through these in 32-byte increments. +However, a GenericEvent may be of arbitrary length longer than 32 bytes, +so any GenericEvent in this list would result in subsequent events to be +misparsed. + +Additional, the swapped event is written into a stack-allocated struct +xEvent (size 32 bytes). For any GenericEvent longer than 32 bytes, +swapping the event may thus smash the stack like an avocado on toast. + +Catch this case early and return BadValue for any GenericEvent. +Which is what would happen in unswapped setups anyway since XTest +doesn't support GenericEvent. + +CVE-2022-46340, ZDI-CAN 19265 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> +Acked-by: Olivier Fourdan <ofourdan@redhat.com> +(cherry picked from commit b320ca0ffe4c0c872eeb3a93d9bde21f765c7c63) +--- + Xext/xtest.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/Xext/xtest.c b/Xext/xtest.c +index 540d270a1c0d..e5d38aa61253 100644 +--- a/Xext/xtest.c ++++ b/Xext/xtest.c +@@ -502,10 +502,11 @@ XTestSwapFakeInput(ClientPtr client, xReq * req) + + nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent); + for (ev = (xEvent *) &req[1]; --nev >= 0; ev++) { ++ int evtype = ev->u.u.type & 0x177; + /* Swap event */ +- proc = EventSwapVector[ev->u.u.type & 0177]; ++ proc = EventSwapVector[evtype]; + /* no swapping proc; invalid event type? */ +- if (!proc || proc == NotImplemented) { ++ if (!proc || proc == NotImplemented || evtype == GenericEvent) { + client->errorValue = ev->u.u.type; + return BadValue; + } +-- +2.39.0 + diff --git a/debian/patches/14_Xi-disallow-passive-grabs-with-a-detail-255.patch b/debian/patches/14_Xi-disallow-passive-grabs-with-a-detail-255.patch new file mode 100644 index 0000000000000000000000000000000000000000..0b93121293cf919d33475e8dfa2a9bd98eb80c3d --- /dev/null +++ b/debian/patches/14_Xi-disallow-passive-grabs-with-a-detail-255.patch @@ -0,0 +1,85 @@ +From: Peter Hutterer <peter.hutterer@who-t.net> +Date: Tue, 29 Nov 2022 13:55:32 +1000 +Subject: Xi: disallow passive grabs with a detail > 255 +Origin: https://gitlab.freedesktop.org/xorg/xserver/commit/a6c0d7b142e762a6b9934a23e060ea91ff5afcea +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2022-46341 +Bug-Debian: https://bugs.debian.org/1026071 + +The XKB protocol effectively prevents us from ever using keycodes above +255. For buttons it's theoretically possible but realistically too niche +to worry about. For all other passive grabs, the detail must be zero +anyway. + +This fixes an OOB write: + +ProcXIPassiveUngrabDevice() calls DeletePassiveGrabFromList with a +temporary grab struct which contains tempGrab->detail.exact = stuff->detail. +For matching existing grabs, DeleteDetailFromMask is called with the +stuff->detail value. This function creates a new mask with the one bit +representing stuff->detail cleared. + +However, the array size for the new mask is 8 * sizeof(CARD32) bits, +thus any detail above 255 results in an OOB array write. + +CVE-2022-46341, ZDI-CAN 19381 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> +Acked-by: Olivier Fourdan <ofourdan@redhat.com> +(cherry picked from commit 51eb63b0ee1509c6c6b8922b0e4aa037faa6f78b) +--- + Xi/xipassivegrab.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c +index 2769fb7c940d..c9ac2f855379 100644 +--- a/Xi/xipassivegrab.c ++++ b/Xi/xipassivegrab.c +@@ -137,6 +137,12 @@ ProcXIPassiveGrabDevice(ClientPtr client) + return BadValue; + } + ++ /* XI2 allows 32-bit keycodes but thanks to XKB we can never ++ * implement this. Just return an error for all keycodes that ++ * cannot work anyway, same for buttons > 255. */ ++ if (stuff->detail > 255) ++ return XIAlreadyGrabbed; ++ + if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1], + stuff->mask_len * 4) != Success) + return BadValue; +@@ -207,14 +213,8 @@ ProcXIPassiveGrabDevice(ClientPtr client) + ¶m, XI2, &mask); + break; + case XIGrabtypeKeycode: +- /* XI2 allows 32-bit keycodes but thanks to XKB we can never +- * implement this. Just return an error for all keycodes that +- * cannot work anyway */ +- if (stuff->detail > 255) +- status = XIAlreadyGrabbed; +- else +- status = GrabKey(client, dev, mod_dev, stuff->detail, +- ¶m, XI2, &mask); ++ status = GrabKey(client, dev, mod_dev, stuff->detail, ++ ¶m, XI2, &mask); + break; + case XIGrabtypeEnter: + case XIGrabtypeFocusIn: +@@ -334,6 +334,12 @@ ProcXIPassiveUngrabDevice(ClientPtr client) + return BadValue; + } + ++ /* We don't allow passive grabs for details > 255 anyway */ ++ if (stuff->detail > 255) { ++ client->errorValue = stuff->detail; ++ return BadValue; ++ } ++ + rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess); + if (rc != Success) + return rc; +-- +2.39.0 + diff --git a/debian/patches/15_Xext-free-the-XvRTVideoNotify-when-turning-off-from-.patch b/debian/patches/15_Xext-free-the-XvRTVideoNotify-when-turning-off-from-.patch new file mode 100644 index 0000000000000000000000000000000000000000..29fe8bea06295527956ab29fec5d0a5e721e5a4e --- /dev/null +++ b/debian/patches/15_Xext-free-the-XvRTVideoNotify-when-turning-off-from-.patch @@ -0,0 +1,76 @@ +From: Peter Hutterer <peter.hutterer@who-t.net> +Date: Wed, 30 Nov 2022 11:20:40 +1000 +Subject: Xext: free the XvRTVideoNotify when turning off from the same client +Origin: https://gitlab.freedesktop.org/xorg/xserver/commit/67927cc41f452228188bbe2aa34a9ee4a9ce0c6b +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2022-46342 +Bug-Debian: https://bugs.debian.org/1026071 + +This fixes a use-after-free bug: + +When a client first calls XvdiSelectVideoNotify() on a drawable with a +TRUE onoff argument, a struct XvVideoNotifyRec is allocated. This struct +is added twice to the resources: + - as the drawable's XvRTVideoNotifyList. This happens only once per + drawable, subsequent calls append to this list. + - as the client's XvRTVideoNotify. This happens for every client. + +The struct keeps the ClientPtr around once it has been added for a +client. The idea, presumably, is that if the client disconnects we can remove +all structs from the drawable's list that match the client (by resetting +the ClientPtr to NULL), but if the drawable is destroyed we can remove +and free the whole list. + +However, if the same client then calls XvdiSelectVideoNotify() on the +same drawable with a FALSE onoff argument, only the ClientPtr on the +existing struct was set to NULL. The struct itself remained in the +client's resources. + +If the drawable is now destroyed, the resource system invokes +XvdiDestroyVideoNotifyList which frees the whole list for this drawable +- including our struct. This function however does not free the resource +for the client since our ClientPtr is NULL. + +Later, when the client is destroyed and the resource system invokes +XvdiDestroyVideoNotify, we unconditionally set the ClientPtr to NULL. On +a struct that has been freed previously. This is generally frowned upon. + +Fix this by calling FreeResource() on the second call instead of merely +setting the ClientPtr to NULL. This removes the struct from the client +resources (but not from the list), ensuring that it won't be accessed +again when the client quits. + +Note that the assignment tpn->client = NULL; is superfluous since the +XvdiDestroyVideoNotify function will do this anyway. But it's left for +clarity and to match a similar invocation in XvdiSelectPortNotify. + +CVE-2022-46342, ZDI-CAN 19400 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> +Acked-by: Olivier Fourdan <ofourdan@redhat.com> +(cherry picked from commit b79f32b57cc0c1186b2899bce7cf89f7b325161b) +--- + Xext/xvmain.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Xext/xvmain.c b/Xext/xvmain.c +index f627471938df..2a08f8744a6b 100644 +--- a/Xext/xvmain.c ++++ b/Xext/xvmain.c +@@ -811,8 +811,10 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff) + tpn = pn; + while (tpn) { + if (tpn->client == client) { +- if (!onoff) ++ if (!onoff) { + tpn->client = NULL; ++ FreeResource(tpn->id, XvRTVideoNotify); ++ } + return Success; + } + if (!tpn->client) +-- +2.39.0 + diff --git a/debian/patches/16_Xext-free-the-screen-saver-resource-when-replacing-i.patch b/debian/patches/16_Xext-free-the-screen-saver-resource-when-replacing-i.patch new file mode 100644 index 0000000000000000000000000000000000000000..96b8bdcffa1ecdd9d898ecf30fa1c3efa36ea11c --- /dev/null +++ b/debian/patches/16_Xext-free-the-screen-saver-resource-when-replacing-i.patch @@ -0,0 +1,50 @@ +From: Peter Hutterer <peter.hutterer@who-t.net> +Date: Tue, 29 Nov 2022 14:53:07 +1000 +Subject: Xext: free the screen saver resource when replacing it +Origin: https://gitlab.freedesktop.org/xorg/xserver/commit/d6c7de9eadca980c8ce3b3b7752b67bfa95e6f31 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2022-46343 +Bug-Debian: https://bugs.debian.org/1026071 + +This fixes a use-after-free bug: + +When a client first calls ScreenSaverSetAttributes(), a struct +ScreenSaverAttrRec is allocated and added to the client's +resources. + +When the same client calls ScreenSaverSetAttributes() again, a new +struct ScreenSaverAttrRec is allocated, replacing the old struct. The +old struct was freed but not removed from the clients resources. + +Later, when the client is destroyed the resource system invokes +ScreenSaverFreeAttr and attempts to clean up the already freed struct. + +Fix this by letting the resource system free the old attrs instead. + +CVE-2022-46343, ZDI-CAN 19404 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> +Acked-by: Olivier Fourdan <ofourdan@redhat.com> +(cherry picked from commit 842ca3ccef100ce010d1d8f5f6d6cc1915055900) +--- + Xext/saver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Xext/saver.c b/Xext/saver.c +index f813ba08d13a..fd6153c3136d 100644 +--- a/Xext/saver.c ++++ b/Xext/saver.c +@@ -1051,7 +1051,7 @@ ScreenSaverSetAttributes(ClientPtr client) + pVlist++; + } + if (pPriv->attr) +- FreeScreenAttr(pPriv->attr); ++ FreeResource(pPriv->attr->resource, AttrType); + pPriv->attr = pAttr; + pAttr->resource = FakeClientID(client->index); + if (!AddResource(pAttr->resource, AttrType, (void *) pAttr)) +-- +2.39.0 + diff --git a/debian/patches/17_Xi-return-an-error-from-XI-property-changes-if-verif.patch b/debian/patches/17_Xi-return-an-error-from-XI-property-changes-if-verif.patch new file mode 100644 index 0000000000000000000000000000000000000000..04a65685a9521ed44a0880f3f767e7a9dadcfaef --- /dev/null +++ b/debian/patches/17_Xi-return-an-error-from-XI-property-changes-if-verif.patch @@ -0,0 +1,41 @@ +From: Peter Hutterer <peter.hutterer@who-t.net> +Date: Tue, 29 Nov 2022 13:24:00 +1000 +Subject: Xi: return an error from XI property changes if verification failed +Origin: https://gitlab.freedesktop.org/xorg/xserver/commit/40f431de8a76f737c68ae659fee8472583f15e49 + +Both ProcXChangeDeviceProperty and ProcXIChangeProperty checked the +property for validity but didn't actually return the potential error. + +Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> +Acked-by: Olivier Fourdan <ofourdan@redhat.com> +(cherry picked from commit b8a84cb0f2807b07ab70ca9915fcdee21301b8ca) +--- + Xi/xiproperty.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c +index a36f7d61dfb0..68c362c6287f 100644 +--- a/Xi/xiproperty.c ++++ b/Xi/xiproperty.c +@@ -902,6 +902,8 @@ ProcXChangeDeviceProperty(ClientPtr client) + + rc = check_change_property(client, stuff->property, stuff->type, + stuff->format, stuff->mode, stuff->nUnits); ++ if (rc != Success) ++ return rc; + + len = stuff->nUnits; + if (len > (bytes_to_int32(0xffffffff - sizeof(xChangeDevicePropertyReq)))) +@@ -1141,6 +1143,9 @@ ProcXIChangeProperty(ClientPtr client) + + rc = check_change_property(client, stuff->property, stuff->type, + stuff->format, stuff->mode, stuff->num_items); ++ if (rc != Success) ++ return rc; ++ + len = stuff->num_items; + if (len > bytes_to_int32(0xffffffff - sizeof(xXIChangePropertyReq))) + return BadLength; +-- +2.39.0 + diff --git a/debian/patches/18_Xi-avoid-integer-truncation-in-length-check-of-ProcX.patch b/debian/patches/18_Xi-avoid-integer-truncation-in-length-check-of-ProcX.patch new file mode 100644 index 0000000000000000000000000000000000000000..e9ecb351e433be43a5e0b27c38be124324b9f02d --- /dev/null +++ b/debian/patches/18_Xi-avoid-integer-truncation-in-length-check-of-ProcX.patch @@ -0,0 +1,73 @@ +From: Peter Hutterer <peter.hutterer@who-t.net> +Date: Tue, 29 Nov 2022 13:26:57 +1000 +Subject: Xi: avoid integer truncation in length check of ProcXIChangeProperty +Origin: https://gitlab.freedesktop.org/xorg/xserver/commit/8a1fa008b2f90abce6cabb27d9bc2ed76d07b678 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2022-46344 +Bug-Debian: https://bugs.debian.org/1026071 + +This fixes an OOB read and the resulting information disclosure. + +Length calculation for the request was clipped to a 32-bit integer. With +the correct stuff->num_items value the expected request size was +truncated, passing the REQUEST_FIXED_SIZE check. + +The server then proceeded with reading at least stuff->num_items bytes +(depending on stuff->format) from the request and stuffing whatever it +finds into the property. In the process it would also allocate at least +stuff->num_items bytes, i.e. 4GB. + +The same bug exists in ProcChangeProperty and ProcXChangeDeviceProperty, +so let's fix that too. + +CVE-2022-46344, ZDI-CAN 19405 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> +Acked-by: Olivier Fourdan <ofourdan@redhat.com> +(cherry picked from commit 8f454b793e1f13c99872c15f0eed1d7f3b823fe8) +--- + Xi/xiproperty.c | 4 ++-- + dix/property.c | 3 ++- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c +index 68c362c6287f..066ba21fba51 100644 +--- a/Xi/xiproperty.c ++++ b/Xi/xiproperty.c +@@ -890,7 +890,7 @@ ProcXChangeDeviceProperty(ClientPtr client) + REQUEST(xChangeDevicePropertyReq); + DeviceIntPtr dev; + unsigned long len; +- int totalSize; ++ uint64_t totalSize; + int rc; + + REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq); +@@ -1130,7 +1130,7 @@ ProcXIChangeProperty(ClientPtr client) + { + int rc; + DeviceIntPtr dev; +- int totalSize; ++ uint64_t totalSize; + unsigned long len; + + REQUEST(xXIChangePropertyReq); +diff --git a/dix/property.c b/dix/property.c +index 94ef5a0ec06f..acce94b2c691 100644 +--- a/dix/property.c ++++ b/dix/property.c +@@ -205,7 +205,8 @@ ProcChangeProperty(ClientPtr client) + WindowPtr pWin; + char format, mode; + unsigned long len; +- int sizeInBytes, totalSize, err; ++ int sizeInBytes, err; ++ uint64_t totalSize; + + REQUEST(xChangePropertyReq); + +-- +2.39.0 + diff --git a/debian/patches/19_xkb-reset-the-radio_groups-pointer-to-NULL-after-fre.patch b/debian/patches/19_xkb-reset-the-radio_groups-pointer-to-NULL-after-fre.patch new file mode 100644 index 0000000000000000000000000000000000000000..543347857a27d9d3d2062bfeef56f5a9dd65b31f --- /dev/null +++ b/debian/patches/19_xkb-reset-the-radio_groups-pointer-to-NULL-after-fre.patch @@ -0,0 +1,38 @@ +From: Peter Hutterer <peter.hutterer@who-t.net> +Date: Mon, 5 Dec 2022 15:55:54 +1000 +Subject: xkb: reset the radio_groups pointer to NULL after freeing it +Origin: https://gitlab.freedesktop.org/xorg/xserver/commit/e860bbce4fdb169e84033529331ae2666e679de7 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2022-4283 +Bug-Debian: https://bugs.debian.org/1026071 + +Unlike other elements of the keymap, this pointer was freed but not +reset. On a subsequent XkbGetKbdByName request, the server may access +already freed memory. + +CVE-2022-4283, ZDI-CAN-19530 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> +Acked-by: Olivier Fourdan <ofourdan@redhat.com> +(cherry picked from commit ccdd431cd8f1cabae9d744f0514b6533c438908c) +--- + xkb/xkbUtils.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c +index 8975ade8dde1..9bc51fc714bf 100644 +--- a/xkb/xkbUtils.c ++++ b/xkb/xkbUtils.c +@@ -1327,6 +1327,7 @@ _XkbCopyNames(XkbDescPtr src, XkbDescPtr dst) + } + else { + free(dst->names->radio_groups); ++ dst->names->radio_groups = NULL; + } + dst->names->num_rg = src->names->num_rg; + +-- +2.39.0 + diff --git a/debian/patches/series b/debian/patches/series index faae57a7e96902ad693dd9009aece6e984afd459..771ae65220804aaf7dfccff47e04bfcce87aef05 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -12,3 +12,10 @@ 10_xkb-swap-XkbSetDeviceInfo-and-XkbSetDeviceInfoCheck.patch 11_xkb-proof-GetCountedString-against-request-length-at.patch 12_xkb-fix-some-possible-memleaks-in-XkbGetKbdByName.patch +13_Xtest-disallow-GenericEvents-in-XTestSwapFakeInput.patch +14_Xi-disallow-passive-grabs-with-a-detail-255.patch +15_Xext-free-the-XvRTVideoNotify-when-turning-off-from-.patch +16_Xext-free-the-screen-saver-resource-when-replacing-i.patch +17_Xi-return-an-error-from-XI-property-changes-if-verif.patch +18_Xi-avoid-integer-truncation-in-length-check-of-ProcX.patch +19_xkb-reset-the-radio_groups-pointer-to-NULL-after-fre.patch