mirror of
https://git.yoctoproject.org/poky
synced 2026-06-21 04:53:48 +02:00
xserver-xorg: Fix CVE-2026-34003
Pick patch according to [1] [1] https://lists.x.org/archives/xorg-announce/2026-April/003677.html [2] https://security-tracker.debian.org/tracker/CVE-2026-34003 (From OE-Core rev: 5faf37e3de47291cffed048ae20d91033d94d686) Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> Signed-off-by: Yoann Congal <yoann.congal@smile.fr> Signed-off-by: Paul Barker <paul@pbarker.dev>
This commit is contained in:
committed by
Paul Barker
parent
122701d321
commit
fb0a4eb7a8
@@ -0,0 +1,113 @@
|
|||||||
|
From b85b00dd7b9eee05e3c12e7ad1fce4fc6671507b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||||
|
Date: Mon, 23 Feb 2026 15:52:49 +0100
|
||||||
|
Subject: [PATCH] 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>
|
||||||
|
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2176>
|
||||||
|
|
||||||
|
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/b85b00dd7b9eee05e3c12e7ad1fce4fc6671507b]
|
||||||
|
CVE: CVE-2026-34003
|
||||||
|
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||||
|
---
|
||||||
|
xkb/xkb.c | 15 +++++++++++++++
|
||||||
|
1 file changed, 15 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/xkb/xkb.c b/xkb/xkb.c
|
||||||
|
index 3fcc6c4..0ef634b 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 && doswap) {
|
||||||
|
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 && doswap) {
|
||||||
|
swaps(&mapWire[n].virtualMods);
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
From d38c563fab5c4a554e0939da39e4d1dadef7cbae Mon Sep 17 00:00:00 2001
|
||||||
|
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||||
|
Date: Mon, 2 Mar 2026 14:09:57 +0100
|
||||||
|
Subject: [PATCH] xkb: Add more _XkbCheckRequestBounds()
|
||||||
|
|
||||||
|
Similar to the recent fixes, add more _XkbCheckRequestBounds() to the
|
||||||
|
functions that loop over the request data, i.e.:
|
||||||
|
|
||||||
|
* CheckKeySyms()
|
||||||
|
* CheckKeyActions()
|
||||||
|
* CheckKeyBehaviors()
|
||||||
|
* CheckVirtualMods()
|
||||||
|
* CheckKeyExplicit()
|
||||||
|
* CheckVirtualModMap()
|
||||||
|
* _XkbSetMapChecks()
|
||||||
|
|
||||||
|
All these are static functions so we can add the client to the parameters
|
||||||
|
without breaking any API.
|
||||||
|
|
||||||
|
See also:
|
||||||
|
CVE-2026-34003, ZDI-CAN-28736, CVE-2026-34002, ZDI-CAN-28737
|
||||||
|
|
||||||
|
v2: Check for "nSyms != 0" in CheckKeySyms() to avoid false positives.
|
||||||
|
|
||||||
|
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||||
|
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||||
|
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2176>
|
||||||
|
|
||||||
|
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/d38c563fab5c4a554e0939da39e4d1dadef7cbae]
|
||||||
|
CVE: CVE-2026-34003
|
||||||
|
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||||
|
---
|
||||||
|
xkb/xkb.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-----------
|
||||||
|
1 file changed, 55 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/xkb/xkb.c b/xkb/xkb.c
|
||||||
|
index 0ef634b..6320914 100644
|
||||||
|
--- a/xkb/xkb.c
|
||||||
|
+++ b/xkb/xkb.c
|
||||||
|
@@ -1752,6 +1752,11 @@ CheckKeySyms(ClientPtr client,
|
||||||
|
KeySym *pSyms;
|
||||||
|
register unsigned nG;
|
||||||
|
|
||||||
|
+ /* Check we received enough data to read the next xkbSymMapWireDesc */
|
||||||
|
+ if (!_XkbCheckRequestBounds(client, req, wire, wire + 1)) {
|
||||||
|
+ *errorRtrn = _XkbErrCode3(0x18, i + req->firstKeySym, i);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
if (client->swapped && doswap) {
|
||||||
|
swaps(&wire->nSyms);
|
||||||
|
}
|
||||||
|
@@ -1790,6 +1795,12 @@ CheckKeySyms(ClientPtr client,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pSyms = (KeySym *) &wire[1];
|
||||||
|
+ if (wire->nSyms != 0) {
|
||||||
|
+ if (!_XkbCheckRequestBounds(client, req, pSyms, &pSyms[wire->nSyms])) {
|
||||||
|
+ *errorRtrn = _XkbErrCode3(0x19, i + req->firstKeySym, wire->nSyms);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms];
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1813,11 +1824,12 @@ CheckKeySyms(ClientPtr client,
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-CheckKeyActions(XkbDescPtr xkb,
|
||||||
|
- xkbSetMapReq * req,
|
||||||
|
- int nTypes,
|
||||||
|
- CARD8 *mapWidths,
|
||||||
|
- CARD16 *symsPerKey, CARD8 **wireRtrn, int *nActsRtrn)
|
||||||
|
+CheckKeyActions(ClientPtr client,
|
||||||
|
+ XkbDescPtr xkb,
|
||||||
|
+ xkbSetMapReq * req,
|
||||||
|
+ int nTypes,
|
||||||
|
+ CARD8 *mapWidths,
|
||||||
|
+ CARD16 *symsPerKey, CARD8 **wireRtrn, int *nActsRtrn)
|
||||||
|
{
|
||||||
|
int nActs;
|
||||||
|
CARD8 *wire = *wireRtrn;
|
||||||
|
@@ -1828,6 +1840,11 @@ CheckKeyActions(XkbDescPtr xkb,
|
||||||
|
CHK_REQ_KEY_RANGE2(0x21, req->firstKeyAct, req->nKeyActs, req, (*nActsRtrn),
|
||||||
|
0);
|
||||||
|
for (nActs = i = 0; i < req->nKeyActs; i++) {
|
||||||
|
+ /* Check we received enough data to read the next byte on the wire */
|
||||||
|
+ if (!_XkbCheckRequestBounds(client, req, wire, wire + 1)) {
|
||||||
|
+ *nActsRtrn = _XkbErrCode3(0x24, i + req->firstKeyAct, i);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
if (wire[0] != 0) {
|
||||||
|
if (wire[0] == symsPerKey[i + req->firstKeyAct])
|
||||||
|
nActs += wire[0];
|
||||||
|
@@ -1846,7 +1863,8 @@ CheckKeyActions(XkbDescPtr xkb,
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-CheckKeyBehaviors(XkbDescPtr xkb,
|
||||||
|
+CheckKeyBehaviors(ClientPtr client,
|
||||||
|
+ XkbDescPtr xkb,
|
||||||
|
xkbSetMapReq * req,
|
||||||
|
xkbBehaviorWireDesc ** wireRtrn, int *errorRtrn)
|
||||||
|
{
|
||||||
|
@@ -1872,6 +1890,11 @@ CheckKeyBehaviors(XkbDescPtr xkb,
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < req->totalKeyBehaviors; i++, wire++) {
|
||||||
|
+ /* Check we received enough data to read the next behavior */
|
||||||
|
+ if (!_XkbCheckRequestBounds(client, req, wire, wire + 1)) {
|
||||||
|
+ *errorRtrn = _XkbErrCode3(0x36, first, i);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
if ((wire->key < first) || (wire->key > last)) {
|
||||||
|
*errorRtrn = _XkbErrCode4(0x33, first, last, wire->key);
|
||||||
|
return 0;
|
||||||
|
@@ -1897,7 +1920,8 @@ CheckKeyBehaviors(XkbDescPtr xkb,
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-CheckVirtualMods(XkbDescRec * xkb,
|
||||||
|
+CheckVirtualMods(ClientPtr client,
|
||||||
|
+ XkbDescRec * xkb,
|
||||||
|
xkbSetMapReq * req, CARD8 **wireRtrn, int *errorRtrn)
|
||||||
|
{
|
||||||
|
register CARD8 *wire = *wireRtrn;
|
||||||
|
@@ -1909,12 +1933,18 @@ CheckVirtualMods(XkbDescRec * xkb,
|
||||||
|
if (req->virtualMods & bit)
|
||||||
|
nMods++;
|
||||||
|
}
|
||||||
|
+ /* Check we received enough data for the number of virtual mods expected */
|
||||||
|
+ if (!_XkbCheckRequestBounds(client, req, wire, wire + XkbPaddedSize(nMods))) {
|
||||||
|
+ *errorRtrn = _XkbErrCode3(0x37, nMods, i);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
*wireRtrn = (wire + XkbPaddedSize(nMods));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-CheckKeyExplicit(XkbDescPtr xkb,
|
||||||
|
+CheckKeyExplicit(ClientPtr client,
|
||||||
|
+ XkbDescPtr xkb,
|
||||||
|
xkbSetMapReq * req, CARD8 **wireRtrn, int *errorRtrn)
|
||||||
|
{
|
||||||
|
register CARD8 *wire = *wireRtrn;
|
||||||
|
@@ -1940,6 +1970,11 @@ CheckKeyExplicit(XkbDescPtr xkb,
|
||||||
|
}
|
||||||
|
start = wire;
|
||||||
|
for (i = 0; i < req->totalKeyExplicit; i++, wire += 2) {
|
||||||
|
+ /* Check we received enough data to read the next two bytes */
|
||||||
|
+ if (!_XkbCheckRequestBounds(client, req, wire, wire + 2)) {
|
||||||
|
+ *errorRtrn = _XkbErrCode4(0x54, first, last, i);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
if ((wire[0] < first) || (wire[0] > last)) {
|
||||||
|
*errorRtrn = _XkbErrCode4(0x53, first, last, wire[0]);
|
||||||
|
return 0;
|
||||||
|
@@ -1995,7 +2030,8 @@ CheckModifierMap(ClientPtr client, XkbDescPtr xkb, xkbSetMapReq * req,
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-CheckVirtualModMap(XkbDescPtr xkb,
|
||||||
|
+CheckVirtualModMap(ClientPtr client,
|
||||||
|
+ XkbDescPtr xkb,
|
||||||
|
xkbSetMapReq * req,
|
||||||
|
xkbVModMapWireDesc ** wireRtrn, int *errRtrn)
|
||||||
|
{
|
||||||
|
@@ -2019,6 +2055,11 @@ CheckVirtualModMap(XkbDescPtr xkb,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < req->totalVModMapKeys; i++, wire++) {
|
||||||
|
+ /* Check we received enough data to read the next virtual mod map key */
|
||||||
|
+ if (!_XkbCheckRequestBounds(client, req, wire, wire + 1)) {
|
||||||
|
+ *errRtrn = _XkbErrCode3(0x74, first, i);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
if ((wire->key < first) || (wire->key > last)) {
|
||||||
|
*errRtrn = _XkbErrCode4(0x73, first, last, wire->key);
|
||||||
|
return 0;
|
||||||
|
@@ -2563,7 +2604,7 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((req->present & XkbKeyActionsMask) &&
|
||||||
|
- (!CheckKeyActions(xkb, req, nTypes, mapWidths, symsPerKey,
|
||||||
|
+ (!CheckKeyActions(client, xkb, req, nTypes, mapWidths, symsPerKey,
|
||||||
|
(CARD8 **) &values, &nActions))) {
|
||||||
|
client->errorValue = nActions;
|
||||||
|
return BadValue;
|
||||||
|
@@ -2571,18 +2612,18 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
|
||||||
|
|
||||||
|
if ((req->present & XkbKeyBehaviorsMask) &&
|
||||||
|
(!CheckKeyBehaviors
|
||||||
|
- (xkb, req, (xkbBehaviorWireDesc **) &values, &error))) {
|
||||||
|
+ (client, xkb, req, (xkbBehaviorWireDesc **) &values, &error))) {
|
||||||
|
client->errorValue = error;
|
||||||
|
return BadValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((req->present & XkbVirtualModsMask) &&
|
||||||
|
- (!CheckVirtualMods(xkb, req, (CARD8 **) &values, &error))) {
|
||||||
|
+ (!CheckVirtualMods(client, xkb, req, (CARD8 **) &values, &error))) {
|
||||||
|
client->errorValue = error;
|
||||||
|
return BadValue;
|
||||||
|
}
|
||||||
|
if ((req->present & XkbExplicitComponentsMask) &&
|
||||||
|
- (!CheckKeyExplicit(xkb, req, (CARD8 **) &values, &error))) {
|
||||||
|
+ (!CheckKeyExplicit(client, xkb, req, (CARD8 **) &values, &error))) {
|
||||||
|
client->errorValue = error;
|
||||||
|
return BadValue;
|
||||||
|
}
|
||||||
|
@@ -2593,7 +2634,7 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
|
||||||
|
}
|
||||||
|
if ((req->present & XkbVirtualModMapMask) &&
|
||||||
|
(!CheckVirtualModMap
|
||||||
|
- (xkb, req, (xkbVModMapWireDesc **) &values, &error))) {
|
||||||
|
+ (client, xkb, req, (xkbVModMapWireDesc **) &values, &error))) {
|
||||||
|
client->errorValue = error;
|
||||||
|
return BadValue;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
||||||
@@ -9,6 +9,8 @@ SRC_URI += "file://0001-xf86pciBus.c-use-Intel-ddx-only-for-pre-gen4-hardwar.pat
|
|||||||
file://CVE-2026-34000.patch \
|
file://CVE-2026-34000.patch \
|
||||||
file://CVE-2026-34001.patch \
|
file://CVE-2026-34001.patch \
|
||||||
file://CVE-2026-34002.patch \
|
file://CVE-2026-34002.patch \
|
||||||
|
file://CVE-2026-34003-1.patch \
|
||||||
|
file://CVE-2026-34003-2.patch \
|
||||||
"
|
"
|
||||||
SRC_URI[sha256sum] = "c878d1930d87725d4a5bf498c24f4be8130d5b2646a9fd0f2994deff90116352"
|
SRC_URI[sha256sum] = "c878d1930d87725d4a5bf498c24f4be8130d5b2646a9fd0f2994deff90116352"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user