xserver/Xext
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Peter Hutterer 0cdd8bbd25 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>
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-06-03 19:08:00 +02:00
..
damage Xext: damage: turn around return values on doDamageCreate() 2026-04-29 11:29:42 +02:00
dri2 Xext: dri2: pci_ids: fix includes (silence clang-tidy) 2026-04-24 18:15:46 +02:00
namespace Xext: namespace: Allow using tabs as delimeters 2026-01-22 08:57:15 +01:00
bigreq.c Xext: bigreq: drop unnecessary includes 2026-04-29 15:06:50 +02:00
dpms.c Xext: dpms: use new X_REPLY_FIELD_* macros 2026-04-28 17:32:39 +02:00
dpmsproc.h xext: move include guards up to wrap the whole file 2025-11-21 15:20:11 +01:00
geext.c Xext: geext: use new X_REPLY_FIELD_* macros 2026-04-28 17:12:01 +02:00
geext_priv.h include: fix missing includes of <X11/Xfuncproto.h> 2026-04-24 13:04:40 +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 Xext: move over public SDK headers to include/ 2026-02-12 19:00:42 +01:00
panoramiX.c panoramiX: fail if we can't allocate our visual arrays 2026-04-30 19:19:15 +02:00
panoramiX.h xext: move include guards up to wrap the whole file 2025-11-21 15:20:11 +01:00
panoramiXh.h Xext: panoramiXh.h: fix missing include of "dix.h" 2026-04-24 16:44:21 +02:00
panoramiXprocs.c Xext: declare rc variables where needed 2026-04-29 10:03:52 +02:00
panoramiXsrv.h xext: move include guards up to wrap the whole file 2025-11-21 15:20:11 +01:00
saver.c saver: re-fetch screen private after CheckScreenPrivate in CreateSaverWindow 2026-06-03 19:08:00 +02:00
security.c Xext: declare rc variables where needed 2026-04-29 10:03:52 +02:00
securitysrv.h Xext: security: drop not needed include 2025-06-12 16:30:13 +02:00
shape.c Xext: declare rc variables where needed 2026-04-29 10:03:52 +02:00
shm.c Xext: shm: declare variables where needed in ProcShmPutImage() 2026-04-29 17:14:00 +02:00
shm_priv.h Xext: move over public SDK headers to include/ 2026-02-12 19:00:42 +01:00
sleepuntil.c Xext: sleepuntil: rename list walk variables 2026-04-29 18:27:55 +02:00
sleepuntil.h xext: move include guards up to wrap the whole file 2025-11-21 15:20:11 +01:00
sync.c sync: fix deletion of counters and fences 2026-06-03 17:49:13 +02:00
syncsrv.h sync: Convert from "CARD64" to int64_t. 2017-09-20 13:19:27 -04:00
xace.c dix: replace XACE_SCREEN_ACCESS by direct callback 2025-10-22 13:53:25 +02:00
xace.h treewide: don't include <region.h> anymore 2025-11-27 19:27:27 +01:00
xacestr.h dix: replace XACE_SCREEN_ACCESS by direct callback 2025-10-22 13:53:25 +02:00
xcmisc.c Xext: xcmisc: brackets around if 2026-04-29 19:27:57 +02:00
xf86bigfont.c Xext: xf86bigfont: brackets around if/for/while 2026-04-29 20:04:10 +02:00
xf86bigfontsrv.h Move extension initialisation prototypes into extinit.h 2012-07-09 23:06:41 -07:00
xres.c Xext: xres: brackets on if's 2026-04-29 19:52:42 +02:00
xselinux.h Xext: selinux.h: fix missing include of <X11/Xmd.h> 2026-04-24 13:04:52 +02:00
xselinux_ext.c Xext: selinux: brackets around if/for 2026-04-29 20:12:39 +02:00
xselinux_hooks.c Xext: xselinux_hooks: brackets on if/for 2026-04-30 11:05:00 +02:00
xselinux_label.c Xext: xselinux_label: brackets around if/for 2026-04-30 11:05:23 +02:00
xselinuxint.h include: drop obsolete registry.h 2024-03-03 23:20:06 +00:00
xtest.c Xext: xtest: bracket around if/for 2026-04-30 12:19:54 +02:00
xvdisp.c Xext: xv: use new X_REPLY_FIELD_* macros 2026-04-28 17:31:20 +02:00
xvdisp.h xext: add/fix include guards where missing/broken 2025-06-27 13:58:05 +02:00
xvdix_priv.h Xext: move over public SDK headers to include/ 2026-02-12 19:00:42 +01:00
xvmain.c Xext: declare rc variables where needed 2026-04-29 10:03:52 +02:00
xvmc.c Xext: declare rc variables where needed 2026-04-29 10:03:52 +02:00