Commit graph

19350 commits

Author SHA1 Message Date
Chang Liu
d15d53ae84 Merge branch 'master' into 'main'
modesetting: match against Multimedia Video Controllers as well

See merge request xorg/xserver!1204
2026-06-02 03:13:40 +00:00
Peter Hutterer
66c4a2a6af glx: fix duplicate tagInfo->vendor = NULL assignment
Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2226>
2026-06-02 01:09:12 +00:00
Peter Hutterer
4809a5e4b8 test/pyxtest: add test for ScreenSaverFreeAttr stale pPriv code path
Add TestScreenSaverFreeAttr which exercises the ScreenSaverFreeAttr
code path by setting attributes, activating the screen saver, then
closing the client connection (triggering resource cleanup).

While ScreenSaverFreeAttr currently does not dereference pPriv after
CheckScreenPrivate, this test verifies the code path is safe and
would catch regressions if future code changes introduced a stale
pointer dereference (same pattern as ZDI-CAN-30168).

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-02 09:41:08 +10:00
Peter Hutterer
3568302483 test/pyxtest: add test for font alias stack overflow (ZDI-CAN-30136)
Add ListFonts, SetFontPath, and GetFontPath protocol builders to
proto/x11.py and a regression test that reproduces the
doListFontsAndAliases stack buffer overflow.

The test creates a temporary font directory with a fonts.alias file
containing an alias whose target name is 400 bytes -- exceeding the
old XLFDMAXFONTNAMELEN of 256 but under libXfont2's MAXFONTNAMELEN of
1024. It prepends this directory to the font path via SetFontPath, then
sends ListFonts matching the alias name. Without the fix, the server
would copy the oversized resolved name into a 256-byte stack buffer,
causing a stack buffer overflow.

ZDI-CAN-30136

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-02 09:41:02 +10:00
Peter Hutterer
6671daeada test/pyxtest: add test for XKB mapWidths stack OOB write (ZDI-CAN-30161)
Add a regression test that reproduces the mapWidths stack buffer overflow
in CheckKeyTypes.

The test sends two XkbSetMap requests: first with firstType=0, nTypes=255,
ResizeTypes to expand the type table to 255 entries, then with
firstType=255, nTypes=10, ResizeTypes. The second request passes the
firstType > num_types check (255 > 255 is false) and computes
nMaps = 255 + 10 = 265. Without the fix, the loop would write
mapWidths[255..264], overflowing 9 bytes past the 256-element stack
buffer into adjacent stack variables.

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-02 09:41:00 +10:00
Peter Hutterer
375d65aa2e test/pyxtest: add test for XKB num_levels stack overflow (ZDI-CAN-30160)
Add a regression test that reproduces the XKB num_levels stack overflow.

The test sends an XkbSetMap request with XkbSetMapResizeTypes that includes
a non-canonical key type with numLevels=255, exceeding XkbMaxShiftLevel
(63). Without the fix, this type would be accepted and stored in the
server's type table. A subsequent ChangeKeyboardMapping would trigger
XkbUpdateKeyTypesFromCore -> XkbKeyTypesForCoreSymbols, where the
oversized num_levels is used as groupsWidth, causing indices into the
tsyms[252] stack buffer to reach up to 1019 and overflow.

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-02 09:39:30 +10:00
Peter Hutterer
57129a43b7 test/pyxtest: add test for ScreenSaver CreateSaverWindow UAF (ZDI-CAN-30168)
Add screensaver protocol builders for SetAttributes, UnsetAttributes, and
ForceScreenSaver, then add a regression test that reproduces the
CreateSaverWindow use-after-free.

The test sequence:
1. SetAttributes(root, 100x100, mask=0) - creates screen private with attr
2. ForceScreenSaver(Active) - creates the saver window
3. UnsetAttributes(root) - clears pPriv->attr to NULL
4. ForceScreenSaver(Active) - re-enters CreateSaverWindow

Without the fix, step 4 triggers CheckScreenPrivate which finds all fields
empty (attr=NULL, events=NULL, hasWindow=FALSE, installedMap=None), frees
pPriv, and sets the screen private to NULL. The function then dereferences
the freed pPriv->attr pointer, causing a use-after-free.

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Peter Hutterer
471650430b test/pyxtest: add test for SyncChangeCounter trigger list UAF (ZDI-CAN-30164)
Add a regression test that reproduces the SyncChangeCounter use-after-free.

The test creates a counter (value=0) and issues SyncAwait with two
conditions on the same counter, both waiting for value >= 1. A second
client then calls SetCounter to set the value to 100. SyncChangeCounter
iterates triggers; the first fires and FreeAwait frees all sibling trigger
list nodes via SyncDeleteTriggerFromSyncObject. Without the fix, the saved
pnext pointer would dangle, and the next iteration would dereference freed
heap memory.

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Peter Hutterer
d9e5f941d3 test/pyxtest: add tests for miSyncDestroyFence/FreeCounter (ZDI-CAN-30159/30163)
Add SYNC extension protocol builders (proto/sync.py) and a regression test
that reproduces the miSyncDestroyFence and FreeCounter use-after-free.

The first test creates a fence and issues AwaitFence with the same fence ID
listed twice, creating two trigger list nodes pointing into one
SyncAwaitUnion. A second client then destroys the fence. Without the fix,
miSyncDestroyFence would invoke CounterDestroyed before saving the next
pointer, and the first callback would free the SyncAwaitUnion while the
second trigger list node still referenced it.

The second test creates a counter (value=0) and issues SyncAwait with two
conditions on the same counter, both waiting for value >= 1. Since the
counter is 0, Client A blocks. A second client then destroys the counter.
Without the fix, FreeCounter would invoke CounterDestroyed before saving
the next pointer in the trigger list, and the first callback would free
the SyncAwaitUnion while the second trigger node still referenced it.

ZDI-CAN-30163 (FreeCounter)
ZDI-CAN-30159 (miSyncDestroyFence)

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Peter Hutterer
d1f51894f0 test/pyxtest: add test for GLX ChangeDrawableAttributes OOB read (ZDI-CAN-30165)
Add GLX extension protocol builders (proto/glx.py) and a regression test
that reproduces the reversed length check in ChangeDrawableAttributes.

The test creates a GLX context on the root visual, binds it with
MakeCurrent (which auto-creates a GLXDrawable), then sends a
ChangeDrawableAttributes request with length=3 (12 bytes) but
numAttribs=2100. Without the fix, the reversed comparison operator (<
instead of >) would let this undersized request pass validation, and
DoChangeDrawableAttributes would iterate 2100 attribute pairs, reading
far past the 12-byte request buffer.

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Michel Dänzer
339c279514 dri2: Deduplicate attachments in do_get_buffer
It was always the intention of the DRI2 protocol that there's at most
one instance of each attachment, and that's how it was implemented in
Mesa.

Since that wasn't enforced though, there might be other clients in the
wild which (e.g. accidentally) request the same attachment multiple
times. So starting to a raise a protocol error in this case now risks
breaking such clients.

Instead, just deduplicate the attachments using a bit-set.

This has a couple of desirable side effects:

* destroy_buffer cannot be called multiple times for the same
  DRI2BufferPtr.
* The client cannot cause the server to allocate a buffers array with
  more entries than there are attachments (currently 11).

Signed-off-by: Michel Dänzer <mdaenzer@redhat.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Michel Dänzer
b7aa65cc3b dri2: Use booleans for (fake) front buffer tracking in do_get_buffers
This works as intended — the (fake) front buffer needs to be added
only if the client didn't request it in the first place — even if the
client requests the same attachment multiple times. This ensures we
never try to access more than (count + 1) entries of the buffers array.

Fixes: ff6c7764c2 ("DRI2: Implement protocol for DRI2GetBuffersWithFormat")
Signed-off-by: Michel Dänzer <mdaenzer@redhat.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Peter Hutterer
bb5158f962 dix: increase XLFDMAXFONTNAMELEN to match libXfont2's MAXFONTNAMELEN
XLFDMAXFONTNAMELEN was 256 bytes, but libXfont2 defines MAXFONTNAMELEN
as 1024 and allows font names and alias targets up to that length in
fonts.alias files.

doListFontsAndAliases copies the resolved alias target into a
stack-allocated tmp_pattern[XLFDMAXFONTNAMELEN] and then into
c->current.pattern[XLFDMAXFONTNAMELEN] (defined in LFWIstateRec).
doListFontsWithInfo has the same pattern, copying the resolved name into
c->current.pattern[]. With the old 256-byte limit, a fonts.alias entry
with a target name between 257 and 1023 bytes would overflow both
buffers.

An attacker can exploit this by:
  1. Creating a font directory with a fonts.alias containing an alias
     whose target name exceeds 256 bytes
  2. Using SetFontPath to add the malicious directory
  3. Calling ListFonts with the alias name to trigger alias resolution
  4. The oversized resolved name overflows the 256-byte stack buffer

Increase XLFDMAXFONTNAMELEN from 256 to 1024 to match libXfont2's
MAXFONTNAMELEN, ensuring the server can handle any name the font library
produces.

This vulnerability was discovered by:
Anonymous working with TrendAI Zero Day Initiative

ZDI-CAN-30136

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Peter Hutterer
ecc634f1b2 saver: re-fetch screen private after CheckScreenPrivate in CreateSaverWindow
CreateSaverWindow stores pPriv (the ScreenSaverScreenPrivatePtr) in a local
variable via the SetupScreen macro at function entry. When an existing saver
window is being replaced, the function sets pPriv->hasWindow = FALSE and
calls CheckScreenPrivate(). If at this point pPriv->attr is NULL (cleared
by a prior UnsetAttributes call), pPriv->events is NULL, and
pPriv->installedMap is None, then CheckScreenPrivate determines the screen
private is unused, frees it, and sets the screen private pointer to NULL.

The function then continues to dereference the now-freed pPriv on the very
next line (pPriv->attr), resulting in a use-after-free. On glibc 2.34+,
the tcache key at offset 8 within the freed block makes pPriv->attr appear
non-NULL, causing the function to continue operating on garbage data and
eventually crash.

The attack sequence is:
  1. SetAttributes (creates pPriv with pPriv->attr set)
  2. ForceScreenSaver(Active) (creates saver window, pPriv->hasWindow=TRUE)
  3. UnsetAttributes (sets pPriv->attr = NULL)
  4. ForceScreenSaver(Active) (re-enters CreateSaverWindow → UAF)

Fix by re-fetching pPriv from the screen private after CheckScreenPrivate
returns, so the subsequent NULL check correctly detects the freed state.

ScreenSaverFreeAttr has the same pattern, force pPriv to NULL there too
even though it has no real effect.

This vulnerability was discovered by:
Anonymous working with TrendAI Zero Day Initiative

ZDI-CAN-30168

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Peter Hutterer
6d459e4daf glx: fix reversed length check in ChangeDrawableAttributes
The request length validation in __glXDisp_ChangeDrawableAttributes and
__glXDispSwap_ChangeDrawableAttributes uses the wrong comparison direction.
The check tests whether the computed request size is LESS THAN
client->req_len, but should test whether it is GREATER THAN. With the
reversed operator, an undersized request (where numAttribs claims more
attribute pairs than the request actually contains) passes validation.

DoChangeDrawableAttributes then iterates numAttribs attribute pairs starting
from the end of the request header, reading past the actual request data
into adjacent memory. This is an out-of-bounds read that can also cause
an out-of-bounds write when a GLX_EVENT_MASK attribute key is found in the
overread data and its corresponding value is written to pGlxDraw->eventMask.

This patch effectively reverts commit 402b329c3a ("glx: Work around
wrong request lengths sent by mesa"). This was fixed in mesa commit
4324d6fdfbba1 in 2011 (mesa 7.11).

Fixes: 402b329c3a ("glx: Work around wrong request lengths sent by mesa")

This vulnerability was discovered by:
Anonymous working with TrendAI Zero Day Initiative

ZDI-CAN-30165

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Peter Hutterer
867b59b33b xkb: clamp nMaps to mapWidths buffer size in CheckKeyTypes
CheckKeyTypes computes nMaps = firstType + nTypes from client-controlled
request fields when XkbSetMapResizeTypes is set. This value is used to
index mapWidths[], a stack-allocated CARD8 array of XkbMaxLegalKeyCode + 1
(256) elements. No upper bound is enforced on nMaps.

An attacker can first send SetMap(firstType=0, nTypes=255, ResizeTypes) to
set the server's num_types to 255, then send SetMap(firstType=255,
nTypes=10, ResizeTypes). The firstType > num_types check passes because
255 > 255 is false (the check uses > rather than >=). nMaps is then
computed as 265, and the loop writes mapWidths[255..264], overflowing 9
bytes past the stack buffer into adjacent stack variables (symsPerKey[]).

Fix by rejecting requests where firstType + nTypes would exceed the
mapWidths buffer size (XkbMaxLegalKeyCode + 1).

This vulnerability was discovered by:
Anonymous working with TrendAI Zero Day Initiative

ZDI-CAN-30161

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Peter Hutterer
543e108516 xkb: reject key types with num_levels exceeding XkbMaxShiftLevel
CheckKeyTypes validates incoming key type definitions from XkbSetMap
requests but does not enforce an upper bound on numLevels. A client can set
numLevels up to 255 on a non-canonical key type, which is stored in the
server's type table.

When ChangeKeyboardMapping later triggers XkbUpdateKeyTypesFromCore, the
function XkbKeyTypesForCoreSymbols computes groupsWidth from num_levels and
uses the XKB_OFFSET(g, l) = (g * groupsWidth) + l macro to index into
tsyms[], a stack-allocated buffer of XkbMaxSymsPerKey (252) entries. With
num_levels=255, groupsWidth=255, and indices reach up to 3*255+254 = 1019,
overflowing the 252-element stack buffer by 767 KeySym-sized entries.

Fix by rejecting numLevels values greater than XkbMaxShiftLevel (63) in
CheckKeyTypes, alongside the existing lower-bound check for numLevels < 1.

This vulnerability was discovered by:
Anonymous working with TrendAI Zero Day Initiative

ZDI-CAN-30160

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Peter Hutterer
bdd7bf57af sync: restart trigger list iteration in SyncChangeCounter after TriggerFired
This is the equivalent check to miSyncTriggerFence() from
commit f19ab94ba9 ("miext/sync: Fix use-after-free in miSyncTriggerFence()")

When a trigger fires via SyncAwaitTriggerFired, the resulting
FreeResource/FreeAwait call invokes SyncDeleteTriggerFromSyncObject for
every trigger in the same Await group. This unlinks and frees the
corresponding trigger list nodes - potentially including the node pnext
points to.

Fix by restarting iteration from the list head after a trigger fires, since
TriggerFired may have arbitrarily mutated the list. Triggers that have fired
are removed from the list by FreeAwait, so restarting cannot cause infinite
loops.

This vulnerability was discovered by:
Anonymous working with TrendAI Zero Day Initiative

ZDI-CAN-30164

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Peter Hutterer
f5abfb6199 sync: fix deletion of counters and fences
Both FreeCounter() and miSyncDestroyFence() iterate over the trigger list
and invoke the CounterDestroyed callback on each trigger.

The CounterDestroyed callback (e.g. SyncAwaitTriggerFired) may call
FreeResource/FreeAwait, which frees the SyncAwaitUnion containing all
SyncAwait structs in the same Await group.

When multiple conditions in a single Await reference the same sync
object (counter or fence), the first callback frees all SyncAwait
structs while subsequent trigger list nodes still reference them. On the
next iteration, reading ptl->next or ptl->pTrigger dereferences freed
memory, leading to a use-after-free.

We need separate fixes for separate issues here to fix this in one go
- use our null-terminated list macro to make sure our next pointer stays
  valid (the code accessed ptl->next after freeing it)
- update the list head before deleting the trigger, eventually this ends
  up being NULL anyway but meanwhile the list head is a valid list
  during CounterDestroyed
- check if we actually do have a trigger before dereferencing the
  callback
- Set all triggers to NULL if they are shared so we don't dereference
  potentially freed memory

This vulnerability was discovered by:
Anonymous working with TrendAI Zero Day Initiative

ZDI-CAN-30159 (miSyncDestroyFence), ZDI-CAN-30163 (FreeCounter)

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2228>
2026-06-01 08:31:59 +10:00
Richard Purdie
827e82b749 COPYING: Add SPDX-License-Identifier entries
Trying to work out which licences are in the COPYING file is a challenge.
Since I went through and did it, add SPDX-License-Identifier strings before
each one so that others don't have to repeat the work. This makes it easier
to work out which licenses are present.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2218>
2026-05-30 10:32:14 -07:00
Olivier Fourdan
5348d7d792 xwayland: Add have_clipboard flag in pkgconfig file
We use the pkgconfig file to indicate the availability of the command
line options, add the newly added clipboard option there as well.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2223>
2026-05-27 10:04:50 +00:00
Olivier Fourdan
c3198080fc Revert "xwayland: Do not pretend leaving the X11 surface if buttons are down"
Kwin may send button events to Xwayland even when there is no Xwayland
surface with input focus.

With this change applied, that causes spurious input focus changes.

And even with that change reverted, I fail to reproduce the bug from
issue #1811.

This reverts commit 8cb078f8b6.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/work_items/1883
See-also: https://gitlab.freedesktop.org/xorg/xserver/-/work_items/1811
See-also: https://gitlab.freedesktop.org/xorg/xserver/-/work_items/1818
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2194>
2026-05-27 09:36:31 +00:00
Mikhail Dmitrichenko
d6c462f599 xkb: preserve buffer on realloc failure
_Concat() stored the realloc() result directly in its input pointer, so
an allocation failure could drop the only reference to the original
buffer when callers assigned the return value back to their destination
pointer.

Keep the old pointer until realloc() succeeds, avoiding the leak
reported by static analysis.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Signed-off-by: Mikhail Dmitrichenko <m.dmitrichenko222@gmail.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2221>
2026-05-25 12:48:50 +03:00
Alan Coopersmith
ab0a7dacad dix: Fix Collabora's name in copyright notices
Fixes: 3fb258ca2 ("input: add a TouchClassRec to the devices")
Fixes: 7656a9c8d ("dix: Implement internal gesture state handling")

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2219>
2026-05-23 14:19:30 -07:00
Mikhail Dmitrichenko
08e65ce8ae os: check ospoll allocation failures
ospoll_create() initializes backend-specific state immediately after
allocating the ospoll structure. Check the allocation result for each
backend before dereferencing it and return NULL on failure.

Signed-off-by: Mikhail Dmitrichenko <m.dmitrichenko222@gmail.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2217>
2026-05-23 16:30:21 +00:00
Mikhail Dmitrichenko
872ece04f9 xwayland: check queued DRM lease allocation
registry_global() queues DRM lease devices before the root window is
available and initializes the queued entry immediately after malloc().
Return early on allocation failure to avoid dereferencing a NULL
pointer.

Signed-off-by: Mikhail Dmitrichenko <m.dmitrichenko222@gmail.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2217>
2026-05-23 16:30:21 +00:00
Mikhail Dmitrichenko
731cb81ba1 glx: use XNFcallocarray for DRI config allocation
createModeFromConfig() dereferences the allocated GLX DRI config
immediately after allocation. Use the X server no-fail allocator so
allocation failure is handled consistently instead of risking a NULL
dereference.

Signed-off-by: Mikhail Dmitrichenko <m.dmitrichenko222@gmail.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2217>
2026-05-23 16:30:21 +00:00
Peter Hutterer
2409bfda88 pyxtest: rework the request handling to avoid to_bytes() invocations
xclient.send_request() should just take a Request object and handle
to_bytes with the right byte order. This avoids typos/copy-paste errors
in tests when the byte order changes between tests.

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2216>
2026-05-20 23:05:35 +00:00
Peter Hutterer
7e22a5cfb5 pyxtest: replace numerical error values with BadValue, etc.
Let's use human-readable variables for this.

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2216>
2026-05-20 23:05:35 +00:00
Peter Hutterer
a49dc5c7d5 pyxtest: document the --display option in the README
Fixes: 4d79ddd0b4 ("pyxtest: add --display for running a test against a manually started server")
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2216>
2026-05-20 23:05:35 +00:00
Peter Hutterer
54860e6c7f glx: reject negative size in FeedbackBuffer and SelectBuffer requests
Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2206>
2026-05-18 00:09:39 +00:00
Peter Hutterer
b4f2807a40 dix/colormap: fix out-of-bounds read in FindColorInRootCmap
The for loop here always iterates size times but the client controls the
starting offset. When the starting pixel is non-zero (e.g., pixel=10 in
a size=256 colormap), the loop reads from pentFirst[10] through
pentFirst[265], reading 10 entries past the end of the array.

Fix this by wrapping around once we reach size, same as FindColor()
already does.

Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2215>
2026-05-18 00:04:02 +00:00
Peter Hutterer
93d1441487 cursor: fix AllocARGBCursor leak/double-free for psrcbits/pmaskbits/argb
AllocARGBCursor took ownership of the psrcbits/pmaskbits/argb arguments.
But if the initial calloc failed none of them were freed, without the
caller knowing about it. Depending on the code path, those arguments
would thus either leak or be double-freed.

Fix it by always freeing those on error and updating the callers
accordingly.

Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2214>
2026-05-17 23:57:42 +00:00
Peter Hutterer
14caf91be2 pyxtest: fix the vidmode SwitchToModeRequest test
This test was missing SetClientVersion(2) so the reply was a the old 0.x
protocol (and the 36 byte GetModeLine reply). Update so it runs for both
versions now.

Fixes: acbc46e708 ("pyxtest: add tests for the byteswapping patches")
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2213>
2026-05-15 04:14:37 +00:00
Peter Hutterer
9ad275a8f1 pyxtest: require root to run the test as Xorg
This is the easiest way to notify users that it just won't run as-is.

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2213>
2026-05-15 04:14:37 +00:00
Peter Hutterer
87dd72ce99 pyxtest: fix xorg invocations when running from the build dir
We need a proper module tree set up so let's do this via symlinks during
the setup phase and then start the server with that as module path.

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2213>
2026-05-15 04:14:37 +00:00
Alan Coopersmith
a94d6bfac6 meson: raise minimum supported version to meson 1.0.0
Fixes warning:
include/meson.build:208: WARNING: Project targets '>= 0.60.0' but uses
 feature introduced in '1.0.0': "compiler.has_member" keyword argument
 "prefix" of type list.

Fixes: b289d5e2e ("meson: define BSD44SOCKETS and LOCALCONN for xtrans when appropriate")
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2210>
2026-05-15 04:05:58 +00:00
Peter Hutterer
165d2810a0 pyxtest: add test for present notify array byte-swap fix
The test sends a PresentPixmap request with a notify entry from a
byte-swapped client. Without the fix, the window ID in the notify
is not swapped, causing dixLookupWindow to fail with BadWindow.
With the fix, the window ID is correctly interpreted.

See 925edb6c9e ("present: Fix missing byte swaps in sproc_present_pixmap()")

Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2212>
2026-05-15 04:01:11 +00:00
Peter Hutterer
2e876bc39b pyxtest: add test cases for the recent XKB fixes
See https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2208

Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2211>
2026-05-15 03:55:15 +00:00
Olivier Fourdan
58a086d907 config: Fix build with udev disabled
Commit b5b52979 has split the options "udev" and "udev_kms" for systems
without systemd.

Yet, when building with "-Dudev=false", "udev_kms" still defaults to
true.

That breaks the build because "config_udev_odev_probe()" is not defined:

| config/config.c: In function ‘config_odev_probe’:
| config/config.c:77:5: error: implicit declaration of function
|                       ‘config_udev_odev_probe’; did you mean
|                       ‘config_odev_probe’?
|                       [-Wimplicit-function-declaration]
|   77 |     config_udev_odev_probe(probe_callback);
|      |     ^~~~~~~~~~~~~~~~~~~~~~
|      |     config_odev_probe
| config/config.c:77:5: warning: nested extern declaration of
|                       ‘config_udev_odev_probe’ [-Wnested-externs]

Yet, the code of the function "config_udev_odev_probe()" in config/udev.c
is within a "#ifdef udev_kms" conditional, so it is built.

The problem is that the function definition is within an "#ifdef udev"
in the "config_backends.h" header.

So, even though the actual code is compiled, the compiler will fail to
find the function definition, hence the "implicit declaration" error.

To avoid the issue, move the function definition within a separate
"udev_kms" conditional in the "config-backends.h" header file.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/work_items/1890
Fixes: b5b52979 ("meson: split udev from udev_kms which requires systemd")
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2203>
2026-05-11 23:58:47 +00:00
Peter Hutterer
4d79ddd0b4 pyxtest: add --display for running a test against a manually started server
This makes it much easier to debug an individual test since we can now
start an X server via valgrind/gdb/whatever and have the test client
connect to that server.

Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2187>
2026-05-10 23:42:44 +00:00
Peter Hutterer
b9ed4bd4c0 pyxtest: add tests for XI property data byte-swap fix
Add tests for commit b243ef9bc2 ("Xi: Swap property data in
SProcXChangeDeviceProperty/SProcXIChangeProperty").

Both tests set a format=32 property from a byte-swapped client and
read it back, verifying the values round-trip correctly. Without the
property data swap, the stored values have the wrong byte order.

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2187>
2026-05-10 23:42:44 +00:00
Peter Hutterer
acbc46e708 pyxtest: add tests for the byteswapping patches
Not a full list since not all can easily be tested but hey, better than
nothing.
See https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2181

Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2187>
2026-05-10 23:42:44 +00:00
Peter Hutterer
7f7bb53cf9 pyxtest: add test cases for the Screensaver extension CVEs of the last years
Commit 6c4c530107 ("Xext: Fix out of bounds access in SProcScreenSaverSuspend()")

Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2187>
2026-05-10 23:42:44 +00:00
Peter Hutterer
33f3066ddb byxtest: add test cases for the RECORD extension CVEs of the last years
Commit 2902b78535 ("Fix XRecordRegisterClients() Integer underflow")

Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2187>
2026-05-10 23:42:44 +00:00
Peter Hutterer
845eb56df2 pyxtest: add test cases for the various XKB CVEs from the last few years
Commit 446ff2d317 ("Check SetMap request length carefully.")
Commit 6907b6ea2b ("xkb: add request length validation for XkbSetGeometry")
Commit 4cd8533210 ("xkb: Fix buffer overflow in _XkbSetCompatMap()")
Commit f7cd1276bb ("Correct bounds checking in XkbSetNames()")

Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2187>
2026-05-10 23:42:43 +00:00
Peter Hutterer
7d89596e6c pyxtest: add test cases for the RandR extension CVEs of the last years
Commit 541ab2ecd4 ("Xi/randr: fix handling of PropModeAppend/Prepend")
Commit 14f480010a ("randr: avoid integer truncation in length check of ProcRRChange*Property")

Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2187>
2026-05-10 23:42:43 +00:00
Peter Hutterer
fea5cc4b54 pyxtest: add tests for XI property and passive grab CVEs
Commit 541ab2ecd4 ("Xi/randr: fix handling of PropModeAppend/Prepend")
Commit 8f454b793e ("Xi: avoid integer truncation in length check of ProcXIChangeProperty")
Commit 51eb63b0ee ("Xi: disallow passive grabs with a detail > 255")

Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2187>
2026-05-10 23:42:43 +00:00
Peter Hutterer
bea8d65fc8 test: add pytest-based test suite
This test suite is primarily aimed at reproducing the various CVE issues
we've had over the years that require custom crafted protocol requests.
It may also be useful for other testing.

Wrapped in python because pytest is a powerful test suite runner and
writing custom buffers is easy.

The architecture is so that we fork off an X server (one or more of
Xvfb, Xwayland, Xorg) and then run our test clients against that to
check whether we get the right reply, or crash the server, or whether
valgrind complains about something (valgrind is started automatically
for tests that are marked as such).

Tests can be run manually via pytest or via meson test.

Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2187>
2026-05-10 23:42:43 +00:00
Peter Hutterer
2e4a5aecef meson: give the xorg executable an actual name
Matches e.g. xvfb_server and xwayland_server.

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2187>
2026-05-10 23:42:43 +00:00