mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-05-06 11:38:20 +02:00
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 f056ce1cc9)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2178>
This commit is contained in:
parent
70aad8867a
commit
5328a544ba
1 changed files with 7 additions and 3 deletions
10
xkb/xkb.c
10
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;
|
||||
|
|
@ -2568,7 +2572,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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue