xserver/Xext
Peter Hutterer f304b57444 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
(cherry picked from commit f5abfb6199)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2229>
2026-06-02 09:47:17 +10:00
..
bigreq.c Move extension initialisation prototypes into extinit.h 2012-07-09 23:06:41 -07:00
dpms.c Change the DPMS initialization to be conditional on not set from config 2018-06-26 17:14:34 -07:00
dpmsproc.h dpms: Consolidate a bunch of stuff into Xext/dpms.c 2017-03-27 15:59:47 -04:00
geext.c More missing version checks in SProcs 2021-08-08 12:43:01 +00:00
geext.h Move extension initialisation prototypes into extinit.h 2012-07-09 23:06:41 -07:00
geint.h xge: Hide some implementation details 2015-07-08 16:40:58 -04:00
hashtable.c dix: Fix undefined shift in ht_generic_hash 2019-10-15 14:06:30 -04:00
hashtable.h Fix spelling/wording issues 2020-07-05 13:07:33 -07:00
Makefile.am configure: Build hashtable for Xres and glvnd 2020-11-09 09:38:46 +00:00
meson.build meson: hide C API if Xorg is disabled (like autotools) 2021-03-11 00:22:36 +00:00
panoramiX.c panoramix: avoid null dereference in PanoramiXConsolidate() 2025-10-08 17:54:33 +02:00
panoramiX.h Drop trailing whitespaces 2014-11-12 10:25:00 +10:00
panoramiXh.h Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
panoramiXprocs.c dix: Call SourceValidate before GetImage 2019-10-30 16:26:01 +00:00
panoramiXsrv.h Replace 'pointer' type with 'void *' 2014-01-12 10:24:11 -08:00
panoramiXSwap.c dispatch: Mark swapped dispatch as _X_COLD 2017-03-01 10:16:20 -05:00
saver.c Xext: free the screen saver resource when replacing it 2022-12-14 11:24:43 +10:00
security.c dispatch: Mark swapped dispatch as _X_COLD 2017-03-01 10:16:20 -05:00
securitysrv.h Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
shape.c dispatch: Mark swapped dispatch as _X_COLD 2017-03-01 10:16:20 -05:00
shm.c Xext/shm: avoid null dereference in ShmInitScreenPriv() 2025-10-08 17:54:33 +02:00
shmint.h xext: Fix shmint.h to not use headers outside of sdk_HEADERS 2013-11-14 10:22:15 +09:00
sleepuntil.c os: Don't crash in AttendClient if the client is gone 2019-11-19 10:15:05 -08:00
sleepuntil.h Replace 'pointer' type with 'void *' 2014-01-12 10:24:11 -08:00
sync.c sync: fix deletion of counters and fences 2026-06-02 09:47:17 +10:00
syncsdk.h xsync: Add resource inside of SyncCreate, export SyncCreate 2019-04-17 14:01:17 -07:00
syncsrv.h sync: Convert from "CARD64" to int64_t. 2017-09-20 13:19:27 -04:00
vidmode.c Xext/vidmode: avoid null dereference if VidModeCreateMode() allocation fails 2025-10-08 17:54:33 +02:00
xace.c xace: Don't censor window borders 2016-09-28 15:25:07 -04:00
xace.h xace: Remove the audit hooks and tune dispatch 2016-06-10 13:26:19 -04:00
xacestr.h Replace 'pointer' type with 'void *' 2014-01-12 10:24:11 -08:00
xcmisc.c dispatch: Mark swapped dispatch as _X_COLD 2017-03-01 10:16:20 -05:00
xf86bigfont.c xf86bigfont: fix -Wimplicit-function-declaration error 2026-03-28 16:40:00 +00:00
xf86bigfontsrv.h Move extension initialisation prototypes into extinit.h 2012-07-09 23:06:41 -07:00
xres.c Xext/xres: avoid null dereference in ProcXResQueryClients() 2025-10-08 17:54:33 +02:00
xselinux.h Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
xselinux_ext.c Xext/xselinux: add fast path to ProcSELinuxListSelections() 2025-10-08 17:54:33 +02:00
xselinux_hooks.c selinux: Stop using security_context_t 2021-08-17 16:02:39 -04:00
xselinux_label.c Xext/xselinux: avoid memory leak in SELinuxAtomToSID() 2025-10-08 17:54:33 +02:00
xselinuxint.h selinux: Stop using security_context_t 2021-08-17 16:02:39 -04:00
xtest.c Xext/xtest: avoid null dereference in ProcXTestFakeInput() 2025-10-08 17:54:33 +02:00
xvdisp.c Unvalidated lengths 2017-10-10 23:33:34 +02:00
xvdisp.h Fix swapped Xv dispatch under Xinerama. 2007-12-02 14:15:36 -05:00
xvdix.h Drop trailing whitespaces 2014-11-12 10:25:00 +10:00
xvmain.c Xext: free the XvRTVideoNotify when turning off from the same client 2022-12-14 11:24:41 +10:00
xvmc.c dispatch: Mark swapped dispatch as _X_COLD 2017-03-01 10:16:20 -05:00
xvmcext.h Replace 'pointer' type with 'void *' 2014-01-12 10:24:11 -08:00