Timo Aaltonen pushed to branch upstream-unstable at X Strike Force / wayland / 
xwayland


Commits:
0fcbb280 by Octavia Togami at 2026-08-24T16:37:37+02:00
Fix use-after-free caused by duplicate glyphs in one glyphset

We make two glyphsets, GS1 and GS2, both with the same format depth.
GS1 contains any glyph different from the others, let's call it U
(unique). GS2 contains two glyphs with the same content, or at least
sha1 hash. Let's call them A and B.

We first register GS1 and GS2. GS1 has no problems, but before the
fix, registering GS2 breaks accounting in `globalGlyphs`. Since there
is no check for duplicate glyphs within a single set, we make two
`GlyphNew` entries for A and B. Now in the loop at the end, we go over
each entry and call `AddGlyph` and `FreeGlyph`:
1. AddGlyph(GS2, A, idA) inserts A into `globalGlyphs`
2. FreeGlyph(A) drops A's refcnt by one, but as it's being held in
   `globalGlyphs` it's kept alive.
3. AddGlyph(GS2, B, idB) finds A in `globalGlyphs` and reuses it
   instead of inserting B
4. FreeGlyph(B) drops B's refcnt by one (to zero), and B is freed.
   Before the fix, the lookup in `globalGlyphs` finds A's entry, and
   since it isn't a DeletedGlyph, it erroneously removes the
   `gr->glyph` pointing to `A` and decrements `tableEntries`. This
   results in `tableEntries` being off-by-one as `A` is still alive.

Now, we free the glyphsets in a particular order. Freeing GS1 results
in calling FreeGlyph(U), which will decrement U's refcnt to zero, and
free U. This clears out the entry in `globalGlyphs` for U and
decrements `tableEntries`, which due to the earlier error is now zero.
When `FreeGlyphSet` sees this, it clears the `globalGlyphs` for that
format depth. Now freeing A or GS2 (which transitively frees A) will
try to check the `globalGlyphs` at that format depth, but because it
was cleared out this crashes.

The fix here is to change FreeGlyph to only free a glyph from
`globalGlyphs` that is exactly the glyph being freed, so that
FreeGlyph(B) doesn't touch `globalGlyphs` at all. This keeps a proper
count in `tableEntries` and prevents `globalGlyphs[fdepth]` from being
freed before A is freed.

Closes: #1881
See-also: https://gitlab.freedesktop.org/xorg/xserver/-/work_items/1914
(cherry picked from commit 67e7343b588af3852418ea6a0316a326f5c947d2)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2283>

- - - - -
abb1e991 by Michel Dänzer at 2026-09-17T14:04:37+02:00
xwayland/present: Only flip if the window pixmap dimensions match

If they don't, attaching the new buffer changes the dimensions of the
wl_surface representing the window, which can break stuff as described
in https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2044 .

(cherry picked from commit 010c00828a4fec4527f44e3d2a5d34e50dfe835b)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2329>

- - - - -
3e7b1439 by dongshengyuan at 2026-10-05T12:04:48+02:00
enhance: popen-fdopen-error-handling

If fdopen() fails, close the unused pipe fd, free the pid list node,
and restore the smart scheduler signal before returning NULL.
Previously the fd would leak and the node would be added to pidlist
with a NULL fp.

Signed-off-by: dongshengyuan <[email protected]>
(cherry picked from commit 7023ecca450be10ef1949389e6a15f416bef2c8b)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
d9c65e23 by Alan Coopersmith at 2026-10-05T12:04:48+02:00
xkb: Fix -Wcalloc-transposed-args warning in _XkbCopyGeom()

Reported by gcc 16.1:
xkb/xkbUtils.c:1440:39: warning: ‘calloc’ sizes specified with ‘sizeof’ in
the earlier argument and not in the later argument [-Wcalloc-transposed-args]
 1440 |             dst->geom = calloc(sizeof(XkbGeometryRec), 1);
      |                                       ^~~~~~~~~~~~~~

Signed-off-by: Alan Coopersmith <[email protected]>
(cherry picked from commit de30aa836538304b2f730d69c845d83a96ac1a16)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
2c64f820 by Alan Coopersmith at 2026-10-05T12:04:48+02:00
test: silence -Wanalyzer-null-argument warnings in strndup tests

Catch malloc failures before calling strcmp() with them.

Signed-off-by: Alan Coopersmith <[email protected]>
(cherry picked from commit e7644f938afa7e9748345e65fb2d7be745c59635)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
d9ff6356 by Alan Coopersmith at 2026-10-05T12:04:48+02:00
Handle -Wimplicit-fallthrough warnings from gcc 16.1

Gets rid of 36 -Wimplicit-fallthrough warnings

Signed-off-by: Alan Coopersmith <[email protected]>
(cherry picked from commit 989e42c1d46a241bd54475d2e062dceed314a97a)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
64cbedc3 by Lukáš Lipinský at 2026-10-05T12:04:48+02:00
Xi: byte-swap DeviceChanged valuator and scroll data

SDeviceChangedEvent left ValuatorClass.value and every ScrollClass-specific 
multi-byte field in server byte order. Swapped clients therefore received 
corrupt current values and scroll metadata.

Swap those fields and extend the protocol event conversion coverage to nonzero 
relative valuator values and both scroll directions and flags.

Signed-off-by: Lukáš Lipinský 
<[email protected]>
(cherry picked from commit cf91b97d6c7c3ec24a4b161484921f5d4ca5a6de)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
56e4387f by Lukáš Lipinský at 2026-10-05T12:04:48+02:00
Xi: byte-swap XIQueryDevice ScrollClass flags

SwapScrollInfo converted the other multi-byte ScrollClass fields but left flags 
in server byte order. Swap it as well and decode the field in the 
swapped-client protocol test so nonzero flags exercise the wire representation.

Signed-off-by: Lukáš Lipinský 
<[email protected]>
(cherry picked from commit 8033c4d93ea140025fea5e7294bb4e92c0cd6af5)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
64e4540d by Jeremy Huddleston Sequoia at 2026-10-05T12:04:48+02:00
RegionValidate: Fix double free of badreg->data on the error path

RegionValidate() copies *badreg into ri[0].reg, so ri[0].reg.data aliases 
badreg->data. A later
RECTALLOC_BAIL() can realloc() that block and move it, updating ri[0].reg.data 
but not badreg->data. On
the bail path, freeing ri[0].reg.data and then calling RegionBreak(badreg) 
frees badreg->data a second
time, which by then is a stale pointer into memory already freed or reallocated 
to something else.

Signed-off-by: Jeremy Huddleston Sequoia <[email protected]>
(cherry picked from commit 4ef1b4cd2690c6d8e4b029b02bf707cb04d0da24)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
1b4538d7 by Jeremy Huddleston Sequoia at 2026-10-05T12:04:48+02:00
damage: Unlink a damage from the list it was actually inserted on

DamageRegister() chooses which list a damage is linked onto via 
getDrawableDamageRef(), but DamageUnregister() and
damageSetWindowPixmap() re-derived that list at removal time.  For a window the 
answer depends on the window pixmap,
which changes while the damage is registered (Composite redirection, rootless 
drawing and Present flips all swap it), so
the removal could consult a different list than the one the damage was inserted 
onto.  It then silently found nothing --
DAMAGE_VALIDATE_ENABLE is off, so the diagnostic is compiled out -- and left an 
unregistered, often freed, damage linked
where damageRegionAppend() would later dereference its NULL pDrawable and crash.

Record the list head when linking a damage and always unlink from that, which 
also drops a use-after-free read of the
old window pixmap in damageSetWindowPixmap(): rootless frees its scratch pixmap 
before restoring the pre-drawing window
pixmaps, so the pixmap consulted there had already been destroyed.

Fixes: https://github.com/XQuartz/XQuartz/issues/406

Signed-off-by: Jeremy Huddleston Sequoia <[email protected]>
(cherry picked from commit da72833185481481052972f031262e94976131ef)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
25171211 by Jeremy Huddleston Sequoia at 2026-10-05T12:04:48+02:00
xkb: Guard XkbAdjustGroup() against a keymap with no groups

When every key in a keymap has zero groups, ctrls->num_groups is 0 and each 
out-of-range action here misbehaves.
XkbWrapIntoRange divides by zero, which is the reported crash.  
XkbClampIntoRange is worse: it computes -1,
returns it through this function's unsigned type, and the callers truncate it 
into XkbStateRec's unsigned char
group fields as 255, after which XkbComputeCompatState() reads map->groups[255] 
out of a four element array and
reports what it finds to clients in the compat state of every core event.  The 
negative-group case adds zero
forever, wedging the server thread, in one path while it holds input_lock.  
XkbComputeDerivedState() treats group
0 as out of range once num_groups is 0, so all of this is reachable from an 
ordinary key event.

XQuartz gets there because it asks for model "empty", whose keycodes file 
declares no key names, so a keymap
compiled at a client's request has no key definitions at all.

Guard the arithmetic itself and not just the places that compute num_groups: 
groups_wrap selects between these
actions and is client settable, and this is exported for DDXes that supply 
their own controls.

Fixes: https://github.com/XQuartz/XQuartz/issues/422
Signed-off-by: Jeremy Huddleston Sequoia <[email protected]>
(cherry picked from commit bdb14dce4b62c37abb3ea9e5edba2eca46b2dbab)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
932253a6 by Jeremy Huddleston Sequoia at 2026-10-05T12:04:48+02:00
xkb: Default to one group whenever a keymap reports none

XkbInitControls() had a fallback to ensure keymaps that defined no symbols at 
all still resulted in one group.
Extend this to cover the case where a keymap reports symbols but no groups.

Fixes: https://github.com/XQuartz/XQuartz/issues/422
Signed-off-by: Jeremy Huddleston Sequoia <[email protected]>
(cherry picked from commit 8e11715024a5167c9554be7b49c4d6ca0bd2c73b)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
e075a6e8 by Jeremy Huddleston Sequoia at 2026-10-05T12:04:48+02:00
xkb: Never recompute a keymap's group count down to zero

Both places that derive ctrls->num_groups from the widest key in the map can 
arrive at zero.  But a keymap in
which no key defines any symbols is legal, so ensure we declare at least one 
group.

Fixes: https://github.com/XQuartz/XQuartz/issues/422
Signed-off-by: Jeremy Huddleston Sequoia <[email protected]>
(cherry picked from commit aa0bc93d27813a33f3484c861a87c26441b5ea2a)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
8ecc6e85 by Jeremy Huddleston Sequoia at 2026-10-05T12:04:48+02:00
xkb: Keep the group counts of a loaded keymap in range

Clamp the count once per key and use it everywhere the key or the keymap is 
indexed with it, while still reading
every symbol the file claimed so that the stream stays in step and the symbol 
array is not left short.

At the other end, a symbols section in which no key defines any group leaves 
the count at the zero it was
allocated with.  This is how XQuartz's keyboard is initialized: model "empty" 
supplies a symbols section that
defines no keys, and a section that defines nothing is still a section, so 
XkbInitControls() sees XkmSymbolsMask
and skips its own single-group default.  The device only survives because 
DarwinKeyboardReloadHandler()
immediately pushes a core keymap that raises the count again.

Fixes: https://github.com/XQuartz/XQuartz/issues/422
Signed-off-by: Jeremy Huddleston Sequoia <[email protected]>
(cherry picked from commit 0c764d98eef507df8e32ac1a84df6782999b5994)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
6b979f54 by stefan11111 at 2026-10-05T12:04:48+02:00
glamor: Set `need_free_region` immediately after pixman region allocation

Otherwise, the region would leak when the pixmap is not in gpu memory

Signed-off-by: stefan11111 <[email protected]>
(cherry picked from commit 41b3d993baf5cbcff7045e63ad0d3d8aebf1dc67)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
c843d3c3 by Leon M. Busch-George at 2026-10-05T12:04:48+02:00
xwayland/glamor/gbm: get_render_node_path without enumeration

Currently, drmGetDevices2 calls opendir and opens FDs to all devices',
causing the kernel to wake up unrelated devices.

With this patch, the file (given as the argument) is opened directly to
check for its type and, optionally, get the render device in one swoop.

The dirs and files opened by drmGetDevices2 use paths anyway (no FDs for
TOCTOU protection).

Co-Authored-By: Michel Dänzer <[email protected]>
Co-Authored-By: stefan11111 <[email protected]>
Signed-off-by: Leon M. Busch-George <[email protected]>
(cherry picked from commit aab1124bb73664809ffc08ded556906269357f2b)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
30c00de9 by Pavel Ondračka at 2026-10-05T12:04:48+02:00
xwayland: let glamor initialize SHM fences

Xwayland sets up shared synchronization before initializing glamor. When
glamor tries to set it up again, the duplicate initialization fails, and
results in missed flush that should happen before the client is allowed
to continue. The client can then start drawing too early. For a
single-buffered GLX drawable, Mesa first copies the window contents into
a fake front buffer. At this point, the window normally contains only
its default background. If this initialization copy runs later, it
overwrites the client's first rendered frame with that background,
causing random piglit glx-visuals-depth and glx-visuals-stencil failures
under Weston.

The race is quite rare for an individual drawable. However, these Piglit
tests iterate over every GLX FBConfig with an X visual, creating and
checking a new window for each one. This provides many single-buffered
drawables and opportunities to hit the race in every invocation, making
the failures frequent in Mesa CI across drivers.

Remove Xwayland's redundant initialization and let glamor initialize the
SHM fence backend before wrapping it and enabling DRI3. Within Xwayland,
only the glamor/DRI3 path needs this shared-fence initialization. When
glamor is disabled, Xwayland does not enable DRI3, and the Sync extension
sets up ordinary fences independently.

Closes: https://gitlab.freedesktop.org/mesa/piglit/-/work_items/105
Fixes: cfa302d6224d ("glamor: Add support for SHM sync fences")
Signed-off-by: Pavel Ondračka <[email protected]>
Reviewed-by: Olivier Fourdan <[email protected]>
(cherry picked from commit 0327c108e9b1b98c98d708b9af3f1aec9af7ea2c)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
3940a46f by Olivier Fourdan at 2026-10-05T12:04:48+02:00
xwayland: Skip xwl_cursor_warped_to() without an xwl_seat

Some compositors may not expose an xwl_seat when running headless, in
which case trying to map the xwl_seat to the input device will cause a
NULL pointer dereference in xwl_cursor_warped_to().

In that case, just return early in xwl_cursor_warped_to(), there is
nothing to do on the Wayland side and the XWarpPointer still updates the
X11 sprite coordinates via SetCursorPosition() as expected.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/work_items/1917
Signed-off-by: Olivier Fourdan <[email protected]>
(cherry picked from commit 4371d6d0ee5be05c8765d5c7c5c31c9fe31d2d1f)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2339>

- - - - -
7d56b6d3 by Olivier Fourdan at 2026-10-06T13:07:40+00:00
xwayland: Handle libxcvt_gen_mode_info() failure

libxcvt_gen_mode_info() can return NULL. Propagate that failure from
xwayland_cvt() instead of dereferencing a NULL pointer.

v2: Use a DebugF() instead of an ErrorF() (Michel)

Assisted-by: AI
Signed-off-by: Olivier Fourdan <[email protected]>
(cherry picked from commit 79774d241aee3c4af8129a25b410b47e8bd297a5)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2340>

- - - - -
6da30a78 by Olivier Fourdan at 2026-10-06T13:07:40+00:00
xwayland: Skip optional RR modes if CVT generation fails

If we fail to add the mode, either skip the mode if it's fake or bail
out nicely (instead of terminating the xserver) if that's an actual
mode. Destroy any modes already created before returning on failure.

v2: Drop the "err" label (Michel)

Assisted-by: AI
Signed-off-by: Olivier Fourdan <[email protected]>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/work_items/1910
(cherry picked from commit ea297c9f224f53e0c7ad40d31cac8d195ac64b46)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2340>

- - - - -
8b0d9436 by Olivier Fourdan at 2026-10-06T13:07:41+00:00
xwayland: Do not fail if cannot add the native or logical mode

If we fail to add either the native mode or the logcal mode, Xwayland
would simply fail out.

Yet, it might be able to continue without either modes, and would
possibly allow applications to run in the other modes when fullscreen.

Signed-off-by: Olivier Fourdan <[email protected]>
Suggested-by: Michel Dänzer <[email protected]>
(cherry picked from commit 037774c7c054d6dda9a7af08fc9a7324158983ed)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2340>

- - - - -
d6ee513e by Olivier Fourdan at 2026-10-06T13:07:41+00:00
xwayland: Update RR modes only if valid

If we fail to get the RR modes (because CVT generation raised an error),
skip updating the RR update - Most likely we shall get further mode
updates from the compositor, so that should not cause a fatal error.

Signed-off-by: Olivier Fourdan <[email protected]>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/work_items/1910
(cherry picked from commit 1d815d00fefd1cbb859a1fa5691bb083329a8cb6)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2340>

- - - - -
db2b484c by Peter Hutterer at 2026-10-07T11:00:13+10:00
xkb: NULL text pointer after free in _CheckSetDoodad error path

_CheckSetDoodad() allocates doodad->text.text via _GetCountedString()
and then attempts to allocate doodad->text.font. If the font string
allocation fails (e.g. because the font string length extends past
the request boundary), the error handler frees doodad->text.text but
does not NULL the pointer. The doodad was already added to the geometry
by XkbAddGeomDoodad() before the string allocations, so when
XkbFreeGeometry() runs cleanup, _XkbClearDoodad() frees the same
dangling pointer again, resulting in a double-free.

NULL the pointer after freeing it to prevent the double-free.

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

ZDI-CAN-31221

CVE-2026-88812

Signed-off-by: Peter Hutterer <[email protected]>
Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit 0d1b1b0bad86c9ea2a3b7ca5a70e681dc69f1ecc)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
68916653 by Peter Hutterer at 2026-10-07T11:00:14+10:00
xkb: allocate names->keys to MAP_LENGTH in XkbAllocNames

Commit a3171732d ("xkb: Always use MAP_LENGTH keymap size") converted
most XKB allocation functions to use MAP_LENGTH (256) instead of
max_key_code + 1. It also removed the per-array reallocarray() calls in
XkbChangeKeycodeRange(), replacing them with a memset up to MAP_LENGTH.
However, XkbAllocNames() was missed and still allocates names->keys to
max_key_code + 1.

When a keycodes component with max_key_code < 255 is loaded (e.g.
sun(type6) with max_key_code=132) and then a SetMap request extends
maxKeyCode to 255, XkbChangeKeycodeRange() memsets names->keys from
max_key_code to MAP_LENGTH-1, writing past the undersized allocation.

Fix by allocating names->keys to MAP_LENGTH, consistent with all other
keymap arrays after a3171732d.

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

ZDI-CAN-31941

CVE-2026-93520

Fixes: a3171732da50 ("xkb: Always use MAP_LENGTH keymap size")

Signed-off-by: Peter Hutterer <[email protected]>
Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit b941a473e06f26a407a9adb15759be79f7418e86)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
1b9a4a22 by Peter Hutterer at 2026-10-07T11:00:58+10:00
xkb: widen size_syms, num_syms, size_acts, num_acts to unsigned int

Fields in XkbClientMapRec and XkbServerMapRec that denote size/num
and are unsigned short can result in truncations. For example
when XkbResizeKeyType() computes the new size_syms value as
(nTotal * 15) / 10, the result may be implicitly truncated to 16
bits on assignment. This causes an undersized calloc allocation, and the
subsequent copy loop writes based on the actual (untruncated) key count,
resulting in a heap buffer overflow. A similar truncation may happen
in XkbResizeKeySyms() and XkbResizeKeyActions().

Widen the fields from unsigned short to unsigned int. These are internal
server structures, not wire protocol types.

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

ZDI-CAN-31834

CVE-2026-93518

Signed-off-by: Peter Hutterer <[email protected]>
Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit 89101a6c6618f543d7502f2077c7ef1a507af256)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
21d57a9d by Peter Hutterer at 2026-10-07T11:00:58+10:00
xkb: fix CheckKeySyms overwriting request-range symsPerKey entries

CheckKeySyms() has two loops: the first processes keys in the SetMap
request range, the second fills in any missing keys from the existing
map.

The indexing between the two was inconsistent: the first loop
uses a zero-based index + req->firstKeySym, the second loop used it just
as zero-based index.

Example:
   req->firstKeySym = 50
   req->nKeySyms = 10

  i goes from 0 to 10,
  loop 1 checks [50, 60), changes the width but finishes with i at 10.
  loop 2 then runs over [10, 255(, copying the old keymap width

The second loop overwrites the new widths with the width of the
existing keymap. The subsequent SetKeySyms worked on the new width
and may write fewer actions than the map width.

A subsequent XkbGetMap request would then read XkbKeyNumActions()
entries (derived from the new wider key_sym_map.width) from the shorter
action allocation, causing an out-of-bounds heap read. The overread
bytes would be copied into the GetMap reply and sent back to the client,
producing a bounded heap information disclosure.

This vulnerability was discovered by:
  WONJOON HWANG (@joon1337) working with TrendAI Zero Day Initiative

ZDI-CAN-32408

CVE-2026-93524

Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit cea71d0273e4d5092aa9c6a8a770734c8935c02e)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
a7ab1d9b by Peter Hutterer at 2026-10-07T11:00:58+10:00
randr: fix size and offset in RRChangeProviderProperty PrependMode

RRChangeProviderProperty() has two bugs in the PropModePrepend case:

1. new_value.size is set to 'len' (the new data length) instead of
   'total_len' (len + prop_value->size), losing track of the existing
   data. This also affects PropModeAppend.

2. The old_data offset is computed using prop_value->size instead of
   len. For PrependMode, the layout should be [new(len)][old(size)],
   so old_data should start at len * size_in_bytes.

These bugs are analogous to the ones fixed in RRChangeOutputProperty(),
see commit 541ab2ecd41d ("Xi/randr: fix handling of PropModeAppend/Prepend").

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

ZDI-CAN-31944

CVE-2026-93521

Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Peter Hutterer <[email protected]>
(cherry picked from commit 5dc9efd5a199717b53f70b9c6cd336a522370e46)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
79a4b5a7 by Peter Hutterer at 2026-10-07T11:00:58+10:00
Xi: validate modifier values in ProcXIPassiveUngrabDevice

ProcXIPassiveUngrabDevice() passes client-supplied modifier values
directly to DeletePassiveGrabFromList() without validating them.

DeletePassiveGrabFromList() may reach DeleteDetailFromMask() which uses
BITCLEAR(mask, modifier). The mask is allocated as 8 Mask words (256
bits). A modifier value > 255 causes BITCLEAR to index mask[modifier>>5]
past the allocation, resulting in a controlled single-bit-clear at an
attacker-chosen heap offset.

Add the same modifier validation that CheckGrabValues() uses: reject
modifiers that are not XIAnyModifier and have bits set outside
AllModifiersMask.

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

ZDI-CAN-32366

CVE-2026-93523

Signed-off-by: Peter Hutterer <[email protected]>
Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit 37a1847a60c6799aecf163a5cfa40077a9002675)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
f64e793e by Peter Hutterer at 2026-10-07T11:00:58+10:00
glx: validate dataBytes against cmdlen in RenderLarge first request

__glXDisp_RenderLarge() allocates the large command buffer based on
cmdlen (from hdr->length, the total command size embedded in the
payload), but copies dataBytes (from req->dataBytes, the payload size
of the current sub-request) into it. The existing length check only
validates that the X11 request length is consistent with dataBytes,
not that dataBytes fits within the cmdlen-sized buffer.

A malicious client can set hdr->length to a small value (e.g. 12 bytes)
while sending a large dataBytes (up to ~256KB or more with
BIG-REQUESTS), causing the memcpy to overflow the cmdlen-sized buffer.

Add a check that dataBytes <= cmdlen before the buffer allocation and
copy on the first request.

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

ZDI-CAN-31833

CVE-2026-93517

Signed-off-by: Peter Hutterer <[email protected]>
Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit 2abe4632d793314d3d5f28c19583fb76019f5ce4)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
38339f17 by Peter Hutterer at 2026-10-07T11:00:58+10:00
present: unlink notifies from window list in present_clear_window_notifies

When a window is destroyed, present_clear_window_notifies()
does not remove the notify list node from the window. The notify
may then be freed as part of the window_priv, leaving dangling
pointers in place.

When the vblank owning the notify is later torn down,
present_free_window_notify() calls xorg_list_del() which
writes through these dangling pointers (use-after-free write).

This happens when Present cross-window notifies are used: a
PresentPixmap on window A can reference window B as a notify target.
An untriggered wait_fence keeps the vblank alive so that B can be
destroyed first, creating the dangling-pointer window.

Fix this by calling the free function we have (and moving the window
reset into that function too). present_clear_window_notifies is only
called from one place anyway.

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

ZDI-CAN-31830

CVE-2026-93515

Signed-off-by: Peter Hutterer <[email protected]>
Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit 1b6955c3108e6b43433aefe860070708e6f43d1b)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
649ea4b0 by Peter Hutterer at 2026-10-07T11:00:58+10:00
dix: remove passive grabs referencing a device on removal

Passive grabs (GrabRec) store raw DeviceIntPtr values for both the
grabbed device and the modifier device without any lifetime management.
When a device is removed via XIRemoveMaster, CloseDevice() frees the
device struct, but leaves dangling pointers in grab->modifierDevice
for any grab that used this device.

Subsequent pointer events trigger CheckPassiveGrab() which dereferences
the dangling modifierDevice pointer for XI grabs (the CORE and XI2 paths
reassign it, but the XI path does not).

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

ZDI-CAN-31832

CVE-2026-93516

Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit be572634158850fff4e9829cee88db08d30c9743)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
8a82016f by Peter Hutterer at 2026-10-07T11:00:58+10:00
Xi: add bounds check for barrier events in input_constrain_cursor

input_constrain_cursor() writes barrier hit and leave events into the
InputEventList buffer without checking how many slots remain.
The buffer is allocated by the DDX at GetMaximumEventsNum() (100) entries
and may contain one raw event already. A client can create more than 100
pointer barriers, pre-arm them as released via XIBarrierReleasePointer,
and then trigger a single pointer motion that crosses all barriers
simultaneously. The leave event loop iterates every hit barrier and
writes one event per barrier, overflowing the 100-slot buffer.

In an ideal world we'd change the InternalEvent* pointer to a struct
that contains allocated size, number of events and the pointer itself
but we're crossing public APIs here and that requires an ABI bump.

So we make do with cutting off the number of barrier events at 64 which
should be low enough to not trigger the issue. However, for the 100+
barrier case this means we only send BarierHit events, not BarrierRelease.
Potentially leaving a client stuck.

We mitigate that problem by simply refusing to create more than 32
barriers per screen (which on its own would also fix the issue, but hey,
'doppelt gemoppelt' as they say).

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

ZDI-CAN-31938

CVE-2026-93519

Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit 1f42cc1f00d9c6d46978ae82dba8a52f4d902369)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
b95584b9 by Peter Hutterer at 2026-10-07T11:00:59+10:00
Xi: clean up gesture sprite traces in WindowGone

Gesture sprite traces which have the same 'fixed sprite trace
for the duration of the gesture' logic as touch sprite traces.
Both copy WindowPtrs into the trace without refcounting them.

If a device supports gestures but does not have a TouchClass,
the cleanup skipped over the gesture sprite cleanup, leaving
dangling pointers in place if a sprite trace is destroyed
during an active gesture (i.e. window is removed).

DeliverOneGestureEvent() then dereferences the stale pointer via
DeepestSpriteWin(&gi->sprite)->drawable.id, causing a use-after-free.

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

ZDI-CAN-32753

CVE-2026-93536

Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit efcfd8acc754c5ac4b2555ff375dd5101d735b0a)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
d6deb27b by Peter Hutterer at 2026-10-07T11:00:59+10:00
glamor: size tmp_bits buffer for source coordinate range in upload_boxes

glamor_upload_boxes() allocates the tmp_bits buffer (used for 24-bit to
32-bit depth conversion) based on the destination pixmap height, but
indexes it using source coordinates (y1 - dy_dst + dy_src). When the
source is taller than the destination, the source-relative offset
exceeds the destination height, causing writes past the buffer end.

Size the buffer to account for the source coordinate mapping:
byte_stride * (pixmap->drawable.height - dy_dst + dy_src). This
ensures the buffer covers the full range of source rows that will be
accessed during the upload.

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

ZDI-CAN-32361

CVE-2026-93522

Signed-off-by: Peter Hutterer <[email protected]>
Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit ad26c26bf795e6464f74c8ef5bb1d41403d877ab)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2345>

- - - - -
d958b4e8 by Peter Hutterer at 2026-10-07T11:40:58+10:00
Bump version to 24.1.24

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2348>

- - - - -


36 changed files:

- Xext/xtest.c
- Xi/exevents.c
- Xi/extinit.c
- Xi/xibarriers.c
- Xi/xipassivegrab.c
- Xi/xiquerydevice.c
- dix/devices.c
- dix/region.c
- fb/fb.h
- glamor/glamor_compositerects.c
- glamor/glamor_transfer.c
- glx/glxcmds.c
- hw/xwayland/xwayland-cvt.c
- hw/xwayland/xwayland-glamor-gbm.c
- hw/xwayland/xwayland-output.c
- hw/xwayland/xwayland-present.c
- hw/xwayland/xwayland-screen.c
- include/xkbstr.h
- meson.build
- mi/miarc.c
- miext/damage/damage.c
- miext/damage/damagestr.h
- os/utils.c
- present/present_notify.c
- randr/rrproviderproperty.c
- render/glyph.c
- test/string.c
- test/xi2/protocol-eventconvert.c
- test/xi2/protocol-xiquerydevice.c
- xkb/XKBAlloc.c
- xkb/XKBMAlloc.c
- xkb/ddxBeep.c
- xkb/xkb.c
- xkb/xkbInit.c
- xkb/xkbUtils.c
- xkb/xkmread.c


The diff was not included because it is too large.


View it on GitLab: 
https://salsa.debian.org/xorg-team/wayland/xwayland/-/compare/c5a47fda896aeefbf1d06a73e392a294344f9e1a...d958b4e84c903e8d5851b5ea587b998e4834ce62

-- 
View it on GitLab: 
https://salsa.debian.org/xorg-team/wayland/xwayland/-/compare/c5a47fda896aeefbf1d06a73e392a294344f9e1a...d958b4e84c903e8d5851b5ea587b998e4834ce62
You're receiving this email because of your account on salsa.debian.org. Manage 
all notifications: https://salsa.debian.org/-/profile/notifications | Help: 
https://salsa.debian.org/help


Reply via email to