This fixes a crash when we try to send focus events and dereference
FollowKeyboardWin (0x3) as WindowPtr.
A device set to XSetDeviceFocus(FollowKeyboard) is supposed to follow
the focus of the corresponding master device. During ActivateKeyboard
a slave device is detached from the master for the duration for the grab
so we don't actually have a master to follow - leaving our oldWin set to
the FollowKeyboardWin constant. This later crashes when we try to
dereference it.
Fix this by getting the current master (if any), or the saved master (if
temporarily detached due to a grab). And if failing that, use the VCK
as fallback device - that is technically wrong but it's such a niche use
case that it shouldn't matter.
Reproducer:
window = XCreateSimpleWindow(...)
deviceid = any device that is IsXExtensionKeyboard device
XSetDeviceFocus(deviceid, FollowKeyboard, ...)
XGrabDevice(deviceid, window, ...)
Fixes: f01ee198ff ("dix: don't use inputInfo.keyboard to get the focus window in ActivateKbdGrab")
Found-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Tested-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit cab9017485)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>
When a device is removed while still frozen, the events queued for that
device remain while the device itself is freed.
As a result, replaying the events will cause a use after free.
To avoid the issue, make sure to dequeue and free any pending events on
a frozen device when removed.
CVE-2025-26600, ZDI-CAN-25871
This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 6e0f332ba4)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1831>
CreateCursor returns a cursor with refcount 1 - that refcount is used by
the resource system, any caller needs to call RefCursor to get their own
reference. That happens correctly for normal cursors but for our
rootCursor we keep a variable to the cursor despite not having a ref for
ourselves.
Fix this by reffing/unreffing the rootCursor to ensure our pointer is
valid.
Related to CVE-2025-26594, ZDI-CAN-25544
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit b0a09ba602)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1831>
If a cursor reference count drops to 0, the cursor is freed.
The root cursor however is referenced with a specific global variable,
and when the root cursor is freed, the global variable may still point
to freed memory.
Make sure to prevent the rootCursor from being explicitly freed by a
client.
CVE-2025-26594, ZDI-CAN-25544
This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
v2: Explicitly forbid XFreeCursor() on the root cursor (Peter Hutterer
<peter.hutterer@who-t.net>)
v3: Return BadCursor instead of BadValue (Michel Dänzer
<michel@daenzer.net>)
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Suggested-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 01642f263f)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1831>
Previously, it was looping through sizeof(ev->valuators.mask) * 8
valuators, where valuators.mask is defined as an array of
(MAX_VALUATORS + 7) / 8 entries. Since MAX_VALUATORS is defined as 36,
this made it actually loop through 40 entries. The last 4 bits in this
array should never be set, so we should never access memory outside the
bounds of the arrays defined to be exactly MAX_VALUATORS in length, but
we can make the static analyzer happier and not waste time checking bits
that should never be set.
Found by Oracle Parfait 13.3 static analyzer:
Read outside array bounds [read-outside-array-bounds]:
In array dereference of ev->valuators.data[i] with index i
Array size is 36 elements (of 8 bytes each), index >= 0 and index <= 39
at line 741 of dix/eventconvert.c in function 'eventToDeviceEvent'.
Read outside array bounds [read-outside-array-bounds]:
In array dereference of ev->valuators.data[i] with index i
Array size is 36 elements (of 8 bytes each), index >= 0 and index <= 39
at line 808 of dix/eventconvert.c in function 'eventToRawEvent'.
Read outside array bounds [read-outside-array-bounds]:
In array dereference of ev->valuators.data_raw[i] with index i
Array size is 36 elements (of 8 bytes each), index >= 0 and index <= 39
at line 809 of dix/eventconvert.c in function 'eventToRawEvent'.
Fixes: b2ba77bac ("dix: add EventToXI2 and GetXI2Type.")
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
(cherry picked from commit b65eea43dd)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>
Found by Oracle Parfait 13.3 static analyzer:
Buffer Overflow in STD C function [buffer-overflow-call-stdc]:
Buffer overflow in call to memcpy. Buffer &bev->buttons[4] of
size 24 is written at an offset of 28
Array size is 28 bytes, index is 32
at line 743 of dix/enterleave.c in function
'DeliverStateNotifyEvent'.
Fixes: a85f0d6b9 ("Xi: fix use of button->down - bitflags instead of int arrays.")
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
(cherry picked from commit 4b073d65bb)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>
Clears warning from gcc 14.1:
../dix/resource.c: In function ‘HashResourceID’:
../dix/resource.c:691:44: warning: left shift of negative value
[-Wshift-negative-value]
691 | return (id ^ (id >> numBits)) & ~((~0) << numBits);
| ^~
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
(cherry picked from commit 26a7ab09ea)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1702>
No real harm, but clears warning from gcc 14.1:
../dix/property.c: In function ‘ProcListProperties’:
..//dix/property.c:605:27: warning: dereference of NULL ‘temppAtoms’
[CWE-476] [-Wanalyzer-null-dereference]
605 | *temppAtoms++ = pProp->propertyName;
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
(cherry picked from commit 39f337fd49)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1702>
It shouldn't matter, since it would have a length of 0, but it
clears warnings from gcc 14.1:
../dix/property.c: In function ‘dixChangeWindowProperty’:
../dix/property.c:287:9: warning: use of possibly-NULL ‘data’ where
non-null expected [CWE-690] [-Wanalyzer-possible-null-argument]
287 | memcpy(data, value, totalSize);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../dix/property.c:324:13: warning: use of possibly-NULL ‘data’ where
non-null expected [CWE-690] [-Wanalyzer-possible-null-argument]
324 | memcpy(data, value, totalSize);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
(cherry picked from commit 10cafd0bbe)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1702>
Clears warning from gcc 14.1:
../dix/dixfonts.c: In function ‘SetFontPath’:
../dix/dixfonts.c:1697:28: warning: use of uninitialized value ‘bad’
[CWE-457] [-Wanalyzer-use-of-uninitialized-value]
1697 | client->errorValue = bad;
| ~~~~~~~~~~~~~~~~~~~^~~~~
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
(cherry picked from commit 1a86fba0d9)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1702>
Clears warning from gcc 14.1:
../dix/dixfonts.c:1352:15: warning: use of uninitialized value ‘*c.data’
[CWE-457] [-Wanalyzer-use-of-uninitialized-value]
1352 | free(c->data);
| ~^~~~~~
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
(cherry picked from commit d78836a3a6)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1702>
Clears -Wcalloc-transposed-args warnings from gcc 14.1, such as:
../dix/main.c:165:42: warning: ‘calloc’ sizes specified with ‘sizeof’ in the
earlier argument and not in the later argument [-Wcalloc-transposed-args]
165 | serverClient = calloc(sizeof(ClientRec), 1);
| ^~~~~~~~~
../dix/main.c:165:42: note: earlier argument should specify number of
elements, later size of each element
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
(cherry picked from commit 522f469fe9)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1635>
Since the two DDX'es which had used this key (xnest and xfree86) now using
their own ones, this global key is obsolete and can be removed.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1342>
This header isn't installed, so no external modules could use the
functions declared there. Thus we can unexport it all.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1358>
These aren't used by any drivers/modules, just DDX'es, so no need to export.
Note: tigervnc does use it, but it has it's own DDX, therefore directly
linked in, just like the in-tree DDX'es which doesn't need exporting.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1349>
* this symbol is a server configuration flag (can be passed via cmdline)
for limiting the max size of big-requests. there shouldn't be any need
to use it outside the core X server (in server modules like drivers
or external extension) - therefore unexport it
* in order to reduce namespace pollution of public (server module API)
headers, create a new internal header for those tings (more to come)
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1275>
This breaks the xf86-input-synaptics driver:
synaptics.c: In function 'clickpad_guess_clickfingers':
synaptics.c:2638:5: error: implicit declaration of function 'BUG_RETURN_VAL' [-Werror=implicit-function-declaration]
2638 | BUG_RETURN_VAL(hw->num_mt_mask > sizeof(close_point) * 8, 0);
This reverts commit 442aec2219.
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1316>
The workQueue pointer is currently declared extern, so that WaitForSomething()
can check wether we've got something in the queue and call ProcessWorkQueue()
then.
But that's trivial to simplify: just let ProcessWorkQueue() return early if
workQueue == NULL. Gives us a better isolation of internal stuff as well as
ProcessWorkQueue() protecting itself from possible segfault.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1310>