Rebuild tigervnc against updated xorg-x11-server

Fixes CVE-2026-50256 CVE-2026-50257 CVE-2026-50258 CVE-2026-50259
CVE-2026-50260 CVE-2026-50261 CVE-2026-50262 CVE-2026-50263
CVE-2026-50264

Resolves: RHEL-183998
This commit is contained in:
Jan Grulich 2026-06-17 12:32:38 +02:00
parent f0b7a5de2a
commit 3e7b5e494d
7 changed files with 5 additions and 662 deletions

View File

@ -5,7 +5,7 @@
Name: tigervnc
Version: 1.15.0
Release: 9%{?dist}
Release: 10%{?dist}
Summary: A TigerVNC remote display system
%global _hardened_build 1
@ -57,17 +57,6 @@ Patch209: xorg-CVE-2025-26601.patch
Patch210: xorg-CVE-2025-26601-2.patch
Patch211: xorg-CVE-2025-26601-3.patch
Patch212: xorg-CVE-2025-26601-4.patch
# CVE-2026-33999
Patch213: xorg-CVE-2026-33999.patch
# CVE-2026-34000
Patch214: xorg-CVE-2026-34000.patch
# CVE-2026-34001
Patch215: xorg-CVE-2026-34001.patch
# CVE-2026-34002
Patch216: xorg-CVE-2026-34002.patch
# CVE-2026-34003
Patch217: xorg-CVE-2026-34003-1.patch
Patch218: xorg-CVE-2026-34003-2.patch
BuildRequires: make
BuildRequires: gcc-c++
@ -243,12 +232,6 @@ cat ../xserver120.patch | patch -p1
%patch -P210 -p1 -b .xorg-CVE-2025-26601-2
%patch -P211 -p1 -b .xorg-CVE-2025-26601-3
%patch -P212 -p1 -b .xorg-CVE-2025-26601-4
%patch -P213 -p1 -b .xorg-CVE-2026-33999
%patch -P214 -p1 -b .xorg-CVE-2026-34000
%patch -P215 -p1 -b .xorg-CVE-2026-34001
%patch -P216 -p1 -b .xorg-CVE-2026-34002
%patch -P217 -p1 -b .xorg-CVE-2026-34003-1
%patch -P218 -p1 -b .xorg-CVE-2026-34003-2
popd
%patch -P1 -p1 -b .use-gnome-as-default-session
@ -417,6 +400,10 @@ fi
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}
%changelog
* Wed Jun 17 2026 Jan Grulich <jgrulich@redhat.com> - 1.15.0-10
- Rebuild for updated xorg-x11-server
Resolves: RHEL-183998
* Mon Apr 20 2026 Jan Grulich <jgrulich@redhat.com> - 1.15.0-9
- Fix CVE-2026-33999, CVE-2026-34000, CVE-2026-34001, CVE-2026-34002,
CVE-2026-34003 xorg-x11-server: various XKB and XSYNC vulnerabilities

View File

@ -1,47 +0,0 @@
From 750205e2a8ba90ce532b19a953e8dba221e62648 Mon Sep 17 00:00:00 2001
From: Peter Harris <pharris2@rocketsoftware.com>
Date: Thu, 15 Jan 2026 15:54:09 -0500
Subject: [PATCH xserver 1/6] xkb: fix buffer re-use in _XkbSetCompatMap
If the "compat" buffer has previously been truncated, there will be
unused space in the buffer. The code uses this space, but does not
update the number of valid entries in the buffer.
In the best case, this leads to the new compat entries being ignored. In the
worst case, if there are any "skipped" compat entries, the number of
valid entries will be corrupted, potentially leading to a buffer read
overrun when processing a future request.
Set the number of used "compat" entries when re-using previously
allocated space in the buffer.
CVE-2026-33999, ZDI-CAN-28593
This vulnerability was discovered by:
Jan-Niklas Sohn working with TrendAI Zero Day Initiative
Signed-off-by: Peter Harris <pharris2@rocketsoftware.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit b024ae1749ee58c6fbf863b9a1f5dc440fee2e1b)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2178>
---
xkb/xkb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/xkb/xkb.c b/xkb/xkb.c
index d5f790338..b002da5bc 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -3003,7 +3003,7 @@ _XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
return BadAlloc;
}
}
- else if (req->truncateSI) {
+ else if (req->truncateSI || req->firstSI + req->nSI > compat->num_si) {
compat->num_si = req->firstSI + req->nSI;
}
sym = &compat->sym_interpret[req->firstSI];
--
2.53.0

View File

@ -1,70 +0,0 @@
From 229b7ab7ee48cf9640d635d7db7e32ce00fcb8be Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 18 Feb 2026 16:03:11 +0100
Subject: [PATCH xserver 2/6] xkb: Fix bounds check in _CheckSetGeom()
As reported by valgrind:
== Conditional jump or move depends on uninitialised value(s)
== at 0x5CBE66: SrvXkbAddGeomKeyAlias (XKBGAlloc.c:585)
== by 0x5AC7D5: _CheckSetGeom (xkb.c:5607)
== by 0x5AC952: _XkbSetGeometry (xkb.c:5643)
== by 0x5ACB58: ProcXkbSetGeometry (xkb.c:5684)
== by 0x5B0DAC: ProcXkbDispatch (xkb.c:7070)
== by 0x4A28C5: Dispatch (dispatch.c:553)
== by 0x4B0B24: dix_main (main.c:274)
== by 0x42915E: main (stubmain.c:34)
== Uninitialised value was created by a heap allocation
== at 0x4840B26: malloc (vg_replace_malloc.c:447)
== by 0x5E13B0: AllocateInputBuffer (io.c:981)
== by 0x5E05CD: InsertFakeRequest (io.c:516)
== by 0x4AA860: NextAvailableClient (dispatch.c:3629)
== by 0x5DE0D7: AllocNewConnection (connection.c:628)
== by 0x5DE2C6: EstablishNewConnections (connection.c:692)
== by 0x5DE600: HandleNotifyFd (connection.c:809)
== by 0x5E2598: ospoll_wait (ospoll.c:660)
== by 0x5DA00C: WaitForSomething (WaitFor.c:208)
== by 0x4A26E5: Dispatch (dispatch.c:493)
== by 0x4B0B24: dix_main (main.c:274)
== by 0x42915E: main (stubmain.c:34)
Each key alias entry contains two key names (the alias and the real key
name), each of size XkbKeyNameLength.
The current bounds check only validates the first name, allowing
XkbAddGeomKeyAlias to potentially read uninitialized memory when
accessing the second name at &wire[XkbKeyNameLength].
To fix this, change the value to check to use 2 * XkbKeyNameLength to
validate the bounds.
CVE-2026-34000, ZDI-CAN-28679
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 81b6a34f90b28c32ad499a78a4f391b7c06daea2)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2178>
---
xkb/xkb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/xkb/xkb.c b/xkb/xkb.c
index b002da5bc..9cd2afdb8 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5602,7 +5602,7 @@ _CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client)
}
for (i = 0; i < req->nKeyAliases; i++) {
- if (!_XkbCheckRequestBounds(client, req, wire, wire + XkbKeyNameLength))
+ if (!_XkbCheckRequestBounds(client, req, wire, wire + 2 * XkbKeyNameLength))
return BadLength;
if (XkbAddGeomKeyAlias(geom, &wire[XkbKeyNameLength], wire) == NULL)
--
2.53.0

View File

@ -1,103 +0,0 @@
From f6638d751790ee3f5ca672a9db303bbf5b66d020 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 18 Feb 2026 16:23:23 +0100
Subject: [PATCH xserver 3/6] miext/sync: Fix use-after-free in
miSyncTriggerFence()
As reported by valgrind:
== Invalid read of size 8
== at 0x568C14: miSyncTriggerFence (misync.c:140)
== by 0x540688: ProcSyncTriggerFence (sync.c:1957)
== by 0x540CCC: ProcSyncDispatch (sync.c:2152)
== by 0x4A28C5: Dispatch (dispatch.c:553)
== by 0x4B0B24: dix_main (main.c:274)
== by 0x42915E: main (stubmain.c:34)
== Address 0x17e35488 is 8 bytes inside a block of size 16 free'd
== at 0x4843E43: free (vg_replace_malloc.c:990)
== by 0x53D683: SyncDeleteTriggerFromSyncObject (sync.c:169)
== by 0x53F14D: FreeAwait (sync.c:1208)
== by 0x4DFB06: doFreeResource (resource.c:888)
== by 0x4DFC59: FreeResource (resource.c:918)
== by 0x53E349: SyncAwaitTriggerFired (sync.c:701)
== by 0x568C52: miSyncTriggerFence (misync.c:142)
== by 0x540688: ProcSyncTriggerFence (sync.c:1957)
== by 0x540CCC: ProcSyncDispatch (sync.c:2152)
== by 0x4A28C5: Dispatch (dispatch.c:553)
== by 0x4B0B24: dix_main (main.c:274)
== by 0x42915E: main (stubmain.c:34)
== Block was alloc'd at
== at 0x4840B26: malloc (vg_replace_malloc.c:447)
== by 0x5E50E1: XNFalloc (utils.c:1129)
== by 0x53D772: SyncAddTriggerToSyncObject (sync.c:206)
== by 0x53DCA8: SyncInitTrigger (sync.c:414)
== by 0x5409C7: ProcSyncAwaitFence (sync.c:2089)
== by 0x540D04: ProcSyncDispatch (sync.c:2160)
== by 0x4A28C5: Dispatch (dispatch.c:553)
== by 0x4B0B24: dix_main (main.c:274)
== by 0x42915E: main (stubmain.c:34)
When walking the list of fences to trigger, miSyncTriggerFence() may
call TriggerFence() for the current trigger, which end up calling the
function SyncAwaitTriggerFired().
SyncAwaitTriggerFired() frees the entire await resource, which removes
all triggers from that await - including pNext which may be another
trigger from the same await attached to the same fence.
On the next iteration, ptl = pNext points to freed memory...
To avoid the issue, we need to restart the iteration from the beginning
of the list each time a trigger fires, since the callback can modify the
list.
CVE-2026-34001, ZDI-CAN-28706
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 f19ab94ba9c891d801231654267556dc7f32b5e0)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2178>
---
miext/sync/misync.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/miext/sync/misync.c b/miext/sync/misync.c
index 0931803f6..9a6fbbd4a 100644
--- a/miext/sync/misync.c
+++ b/miext/sync/misync.c
@@ -131,16 +131,22 @@ miSyncDestroyFence(SyncFence * pFence)
void
miSyncTriggerFence(SyncFence * pFence)
{
- SyncTriggerList *ptl, *pNext;
+ SyncTriggerList *ptl;
+ Bool triggered;
pFence->funcs.SetTriggered(pFence);
/* run through triggers to see if any fired */
- for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) {
- pNext = ptl->next;
- if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, 0))
- (*ptl->pTrigger->TriggerFired) (ptl->pTrigger);
- }
+ do {
+ triggered = FALSE;
+ for (ptl = pFence->sync.pTriglist; ptl; ptl = ptl->next) {
+ if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, 0)) {
+ (*ptl->pTrigger->TriggerFired) (ptl->pTrigger);
+ triggered = TRUE;
+ break;
+ }
+ }
+ } while (triggered);
}
SyncScreenFuncsPtr
--
2.53.0

View File

@ -1,91 +0,0 @@
From 5842fd1fcce48ec98bdcce75b804210584ea35e2 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 18 Feb 2026 17:02:09 +0100
Subject: [PATCH xserver 4/6] xkb: Fix out-of-bounds read in CheckModifierMap()
As reported by valgrind:
== Conditional jump or move depends on uninitialised value(s)
== at 0x547E5B: CheckModifierMap (xkb.c:1972)
== by 0x54A086: _XkbSetMapChecks (xkb.c:2574)
== by 0x54A845: ProcXkbSetMap (xkb.c:2741)
== by 0x556EF4: ProcXkbDispatch (xkb.c:7048)
== by 0x454A8C: Dispatch (dispatch.c:553)
== by 0x462CEB: dix_main (main.c:274)
== by 0x405EA7: main (stubmain.c:34)
== Uninitialised value was created by a heap allocation
== at 0x4840B26: malloc (vg_replace_malloc.c:447)
== by 0x592D5A: AllocateInputBuffer (io.c:981)
== by 0x591F77: InsertFakeRequest (io.c:516)
== by 0x45CA27: NextAvailableClient (dispatch.c:3629)
== by 0x58FA81: AllocNewConnection (connection.c:628)
== by 0x58FC70: EstablishNewConnections (connection.c:692)
== by 0x58FFAA: HandleNotifyFd (connection.c:809)
== by 0x593F42: ospoll_wait (ospoll.c:660)
== by 0x58B9B6: WaitForSomething (WaitFor.c:208)
== by 0x4548AC: Dispatch (dispatch.c:493)
== by 0x462CEB: dix_main (main.c:274)
== by 0x405EA7: main (stubmain.c:34)
The issue is that the loop in CheckModifierMap() reads from wire without
verifying that the data is within the request bounds.
The req->totalModMapKeys value could exceed the actual data provided,
causing reads of uninitialized memory.
To fix that issue, we add a bounds check using _XkbCheckRequestBounds,
but for that, we need to also pass a ClientPtr parameter, which is not
a problem since CheckModifierMap() is a private, static function.
CVE-2026-34002, ZDI-CAN-28737
This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit f056ce1cc96ed9261052c31524162c78e458f98c)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2178>
---
xkb/xkb.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 9cd2afdb8..f47ffbc5d 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -1940,8 +1940,8 @@ CheckKeyExplicit(XkbDescPtr xkb,
}
static int
-CheckModifierMap(XkbDescPtr xkb, xkbSetMapReq * req, CARD8 **wireRtrn,
- int *errRtrn)
+CheckModifierMap(ClientPtr client, XkbDescPtr xkb, xkbSetMapReq * req,
+ CARD8 **wireRtrn, int *errRtrn)
{
register CARD8 *wire = *wireRtrn;
CARD8 *start;
@@ -1965,6 +1965,10 @@ CheckModifierMap(XkbDescPtr xkb, xkbSetMapReq * req, CARD8 **wireRtrn,
}
start = wire;
for (i = 0; i < req->totalModMapKeys; i++, wire += 2) {
+ if (!_XkbCheckRequestBounds(client, req, wire, wire + 2)) {
+ *errRtrn = _XkbErrCode3(0x64, req->totalModMapKeys, i);
+ return 0;
+ }
if ((wire[0] < first) || (wire[0] > last)) {
*errRtrn = _XkbErrCode4(0x63, first, last, wire[0]);
return 0;
@@ -2567,7 +2571,7 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
return BadValue;
}
if ((req->present & XkbModifierMapMask) &&
- (!CheckModifierMap(xkb, req, (CARD8 **) &values, &error))) {
+ (!CheckModifierMap(client, xkb, req, (CARD8 **) &values, &error))) {
client->errorValue = error;
return BadValue;
}
--
2.53.0

View File

@ -1,112 +0,0 @@
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

View File

@ -1,221 +0,0 @@
From 7c03d504c2b6ca498e0ff3761b000d77788f0c23 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon, 2 Mar 2026 14:09:57 +0100
Subject: [PATCH xserver 6/6] 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>
(cherry picked from commit d38c563fab5c4a554e0939da39e4d1dadef7cbae)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2178>
---
xkb/xkb.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 55 insertions(+), 14 deletions(-)
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 1ee9cfb6f..f81d20655 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) {
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;
@@ -2562,7 +2603,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;
@@ -2570,18 +2611,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;
}
@@ -2592,7 +2633,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.53.0