Combine poky (Yocto scarthgap), meta-openembedded (scarthgap), and meta-openwrt into a single repository. Components: - poky/ Yocto core framework (BitBake + OE-Core) - meta-openembedded/ Community layers (meta-oe, meta-python, meta-networking) - meta-openwrt/ OpenWrt customization layer - setup-env.sh One-click build environment setup - README.md Project documentation
224 lines
8.1 KiB
Diff
224 lines
8.1 KiB
Diff
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
|
|
|