xserver/Xext
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Peter Hutterer dfc32edebc 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-03 15:33:26 +02:00
..
namespace xext: namespace: fix printf format string 2025-12-11 15:04:42 +01:00
bigreq.c miext: move over extinit_priv.h from include 2025-06-12 17:21:46 +02:00
dpms.c dix: add dixAllocServerXID() 2025-06-12 17:21:48 +02:00
dpmsproc.h Xext: drop checking for HAVE_DIX_CONFIG_H 2025-06-12 16:50:20 +02:00
geext.c miext: move over extinit_priv.h from include 2025-06-12 17:21:46 +02:00
geext_priv.h xext: add/fix include guards where missing/broken 2025-06-27 13:58:05 +02:00
hashtable.c xext: replace xallocarray() by calloc() 2025-06-12 17:21:43 +02:00
hashtable.h Xext: hashtable.h: unexport functions not used by drivers 2025-06-12 16:51:36 +02:00
meson.build treewide: remove "lib" prefix in static_library names (meson) 2025-07-03 12:01:52 +02:00
panoramiX.c panoramiX: fail if we can't allocate our visual arrays 2026-05-01 18:51:19 +02:00
panoramiX.h composite: clean up including panoramix headers 2025-06-12 17:21:43 +02:00
panoramiXh.h xext: add/fix include guards where missing/broken 2025-06-27 13:58:05 +02:00
panoramiXprocs.c panoramix: protect against allocaton failure 2025-06-12 17:21:44 +02:00
panoramiXsrv.h panoramix: export PanoramiXTranslateVisualID for nvidia 2025-06-16 10:32:48 +02:00
panoramiXSwap.c Xext: clean up including panoramix headers 2025-06-12 17:21:43 +02:00
saver.c saver: re-fetch screen private after CheckScreenPrivate in CreateSaverWindow 2026-06-03 15:33:26 +02:00
security.c miext: move over extinit_priv.h from include 2025-06-12 17:21:46 +02:00
securitysrv.h Xext: security: drop not needed include 2025-06-12 16:30:13 +02:00
shape.c Xext: shape: fix non-ximerama build 2025-08-12 11:07:24 +02:00
shm.c Xext/shm: add missing reply byte-swap in ProcShmCreateSegment 2026-04-27 15:20:43 +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 Xext: use calloc() instead of malloc() 2025-06-12 16:48:11 +02:00
sleepuntil.h Xext: drop checking for HAVE_DIX_CONFIG_H 2025-06-12 16:50:20 +02:00
sync.c Xext: sync: NULL pointer protection in FreeCounter() 2026-05-01 18:48:32 +02: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: fix SProcVidModeSwitchToMode swapping only screen field 2026-04-27 15:17:23 +02:00
xace.c xace: export XaceRegisterCallback() and XaceDeleteCallback() 2025-06-12 17:21:45 +02:00
xace.h Xext: Fix typo in xace.h 2025-06-27 17:10:33 +02:00
xacestr.h dix: move over private defintions from selection.h to private header 2025-06-12 17:21:46 +02:00
xcmisc.c miext: move over extinit_priv.h from include 2025-06-12 17:21:46 +02:00
xf86bigfont.c xf86bigfont: fix compiler warning on unused variable 2025-07-01 17:01:07 +02:00
xf86bigfontsrv.h Move extension initialisation prototypes into extinit.h 2012-07-09 23:06:41 -07:00
xres.c Xext/xres: add missing byte-swap of spec entries in SProcXResQueryClientIds 2026-04-27 17:22:20 +02:00
xselinux.h include: unpexport SELINUX_* consts from include/global.h 2024-03-25 19:40:04 +00:00
xselinux_ext.c dix: move over private defintions from selection.h to private header 2025-06-12 17:21:46 +02:00
xselinux_hooks.c selinux: remap security classes on policyload 2026-04-21 10:45:12 +02:00
xselinux_label.c drop obsolete HAVE_DIX_CONFIG_H 2024-10-10 13:38:31 +00:00
xselinuxint.h include: drop obsolete registry.h 2024-03-03 23:20:06 +00:00
xtest.c miext: move over extinit_priv.h from include 2025-06-12 17:21:46 +02:00
xvdisp.c Zero out structs to avoid leaking information via padding 2026-04-27 15:16:13 +02:00
xvdisp.h xext: add/fix include guards where missing/broken 2025-06-27 13:58:05 +02:00
xvdix.h treewide: preemptively revert !1714 where it affects ABI compatibility 2025-06-16 10:32:48 +02:00
xvdix_priv.h Xext: xv: fix redefinition of typedef 'XvPortNotifyPtr' 2025-08-05 18:59:43 +02:00
xvmain.c miext: move over extinit_priv.h from include 2025-06-12 17:21:46 +02:00
xvmc.c xres/xkb/xvmc/modesetting: Fix incorrect pointer data size usage 2025-06-13 13:01:24 +02:00
xvmcext.h xvmc: unexport XvMCFindXvImage() 2024-10-10 19:59:48 +00:00