Resolves: https://redhat.atlassian.net/browse/RHEL-163216 Resolves: https://redhat.atlassian.net/browse/RHEL-163298 Resolves: https://redhat.atlassian.net/browse/RHEL-163229
113 lines
4.4 KiB
Diff
113 lines
4.4 KiB
Diff
From 5d6f378904ec5c7ae22e9ba4afd15e889a0a1df5 Mon Sep 17 00:00:00 2001
|
|
From: Olivier Fourdan <ofourdan@redhat.com>
|
|
Date: Mon, 23 Feb 2026 15:52:49 +0100
|
|
Subject: [PATCH xserver 5/6] xkb: Add additional bound checking in
|
|
CheckKeyTypes()
|
|
|
|
The function CheckKeyTypes() will loop over the client's request but
|
|
won't perform any additional bound checking to ensure that the data
|
|
read remains within the request bounds.
|
|
|
|
As a result, a specifically crafted request may cause CheckKeyTypes() to
|
|
read past the request data, as reported by valgrind:
|
|
|
|
== Invalid read of size 2
|
|
== at 0x5A3D1D: CheckKeyTypes (xkb.c:1694)
|
|
== by 0x5A6A9C: _XkbSetMapChecks (xkb.c:2515)
|
|
== by 0x5A759E: ProcXkbSetMap (xkb.c:2736)
|
|
== by 0x5BF832: SProcXkbSetMap (xkbSwap.c:245)
|
|
== by 0x5C05ED: SProcXkbDispatch (xkbSwap.c:501)
|
|
== by 0x4A20DF: Dispatch (dispatch.c:551)
|
|
== by 0x4B03B4: dix_main (main.c:277)
|
|
== by 0x428941: main (stubmain.c:34)
|
|
== Address is 30 bytes after a block of size 28,672 in arena "client"
|
|
==
|
|
== Invalid read of size 2
|
|
== at 0x5A3AB6: CheckKeyTypes (xkb.c:1669)
|
|
== by 0x5A6A9C: _XkbSetMapChecks (xkb.c:2515)
|
|
== by 0x5A759E: ProcXkbSetMap (xkb.c:2736)
|
|
== by 0x5BF832: SProcXkbSetMap (xkbSwap.c:245)
|
|
== by 0x5C05ED: SProcXkbDispatch (xkbSwap.c:501)
|
|
== by 0x4A20DF: Dispatch (dispatch.c:551)
|
|
== by 0x4B03B4: dix_main (main.c:277)
|
|
== by 0x428941: main (stubmain.c:34)
|
|
== Address is 2 bytes after a block of size 28,672 alloc'd
|
|
== at 0x4848897: realloc (vg_replace_malloc.c:1804)
|
|
== by 0x5E357A: ReadRequestFromClient (io.c:336)
|
|
== by 0x4A1FAB: Dispatch (dispatch.c:519)
|
|
== by 0x4B03B4: dix_main (main.c:277)
|
|
== by 0x428941: main (stubmain.c:34)
|
|
==
|
|
== Invalid write of size 2
|
|
== at 0x5A3AD7: CheckKeyTypes (xkb.c:1669)
|
|
== by 0x5A6A9C: _XkbSetMapChecks (xkb.c:2515)
|
|
== by 0x5A759E: ProcXkbSetMap (xkb.c:2736)
|
|
== by 0x5BF832: SProcXkbSetMap (xkbSwap.c:245)
|
|
== by 0x5C05ED: SProcXkbDispatch (xkbSwap.c:501)
|
|
== by 0x4A20DF: Dispatch (dispatch.c:551)
|
|
== by 0x4B03B4: dix_main (main.c:277)
|
|
== by 0x428941: main (stubmain.c:34)
|
|
== Address is 2 bytes after a block of size 28,672 alloc'd
|
|
== at 0x4848897: realloc (vg_replace_malloc.c:1804)
|
|
== by 0x5E357A: ReadRequestFromClient (io.c:336)
|
|
== by 0x4A1FAB: Dispatch (dispatch.c:519)
|
|
== by 0x4B03B4: dix_main (main.c:277)
|
|
== by 0x428941: main (stubmain.c:34)
|
|
==
|
|
|
|
To avoid that issue, add additional bounds checking within the loops by
|
|
calling _XkbCheckRequestBounds() and report an error if we are to read
|
|
past the client's request.
|
|
|
|
CVE-2026-34003, ZDI-CAN-28736
|
|
|
|
This vulnerability was discovered by:
|
|
Jan-Niklas Sohn working with TrendAI Zero Day Initiative
|
|
|
|
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
|
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
|
|
(cherry picked from commit b85b00dd7b9eee05e3c12e7ad1fce4fc6671507b)
|
|
|
|
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2178>
|
|
---
|
|
xkb/xkb.c | 15 +++++++++++++++
|
|
1 file changed, 15 insertions(+)
|
|
|
|
diff --git a/xkb/xkb.c b/xkb/xkb.c
|
|
index f47ffbc5d..1ee9cfb6f 100644
|
|
--- a/xkb/xkb.c
|
|
+++ b/xkb/xkb.c
|
|
@@ -1639,6 +1639,10 @@ CheckKeyTypes(ClientPtr client,
|
|
for (i = 0; i < req->nTypes; i++) {
|
|
unsigned width;
|
|
|
|
+ if (!_XkbCheckRequestBounds(client, req, wire, wire + 1)) {
|
|
+ *nMapsRtrn = _XkbErrCode3(0x0b, req->nTypes, i);
|
|
+ return 0;
|
|
+ }
|
|
if (client->swapped) {
|
|
swaps(&wire->virtualMods);
|
|
}
|
|
@@ -1664,7 +1668,18 @@ CheckKeyTypes(ClientPtr client,
|
|
xkbModsWireDesc *preWire;
|
|
|
|
mapWire = (xkbKTSetMapEntryWireDesc *) &wire[1];
|
|
+ if (!_XkbCheckRequestBounds(client, req, mapWire,
|
|
+ &mapWire[wire->nMapEntries])) {
|
|
+ *nMapsRtrn = _XkbErrCode3(0x0c, i, wire->nMapEntries);
|
|
+ return 0;
|
|
+ }
|
|
preWire = (xkbModsWireDesc *) &mapWire[wire->nMapEntries];
|
|
+ if (wire->preserve &&
|
|
+ !_XkbCheckRequestBounds(client, req, preWire,
|
|
+ &preWire[wire->nMapEntries])) {
|
|
+ *nMapsRtrn = _XkbErrCode3(0x0d, i, wire->nMapEntries);
|
|
+ return 0;
|
|
+ }
|
|
for (n = 0; n < wire->nMapEntries; n++) {
|
|
if (client->swapped) {
|
|
swaps(&mapWire[n].virtualMods);
|
|
--
|
|
2.53.0
|
|
|