From 449072edb046416a7c9b98497597f304b39f8374 Mon Sep 17 00:00:00 2001 From: LFRon Date: Mon, 24 Aug 2026 12:07:38 +0800 Subject: [PATCH] fix(xwayland): allow cross-UID MIT-SHM by removing NoNewPrivileges and PrivateIPC XWayland spawned by treeland's wlroots needs to attach to SysV shared-memory segments (MIT-SHM / XShmPutImage) created by X11 clients. In a DDM-owned session, Xwayland runs as user "dde" while desktop applications (notably Electron/Chromium apps) may be launched by the real login user. Two systemd service hardening options were blocking this: 1. NoNewPrivileges=true Xwayland requires the cap_ipc_owner file capability on its binary to shmat() segments created by a different UID. no_new_privs makes the kernel ignore file capabilities entirely at execve(), so the capability is never granted and shmat() fails with EACCES. 2. PrivateIPC=true Creates a private IPC namespace for treeland and its children. SysV shm segments created by clients in the host namespace are invisible to Xwayland; shmat() returns EINVAL because the segment does not exist in the private namespace. Both options are now commented out with detailed explanations. Other security hardening (ProtectSystem, ProtectHome, ProtectClock, RestrictSUIDSGID, etc.) is kept intact. The cap_ipc_owner capability is applied to /usr/bin/Xwayland by ddm at startup (see ddm's DaemonApp::applyXwaylandIpcCapability). See also: Xext/shm.c:ProcShmAttach (shmat + shm_access logic). --- misc/systemd/treeland.service.in | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/misc/systemd/treeland.service.in b/misc/systemd/treeland.service.in index 8d1fb57b2c..bd27d62ce7 100644 --- a/misc/systemd/treeland.service.in +++ b/misc/systemd/treeland.service.in @@ -32,7 +32,17 @@ RestartSec=1s StandardOutput=null StandardError=null -NoNewPrivileges=true +# NOTE: NoNewPrivileges=true is intentionally NOT enabled here. +# +# wlroots spawns Xwayland inside treeland, and Xwayland needs to attach to +# SysV shared-memory segments (MIT-SHM / XShmPutImage) created by X11 +# clients that run under a different UID than the Xwayland process itself +# (e.g. Electron apps launched by the real login user against the +# DDM-owned session). This requires the cap_ipc_owner file capability on +# the Xwayland binary (applied by ddm at startup), but no_new_privs makes +# the kernel ignore file capabilities entirely at execve(), leaving such +# windows blank (XShmAttach → BadAccess). See Xext/shm.c:ProcShmAttach. +# NoNewPrivileges=true OOMScoreAdjust=-1000 Nice=-20 CPUWeight=10000 @@ -51,7 +61,16 @@ IOSchedulingPriority=0 # # MemoryDenyWriteExecute=true -PrivateIPC=true +# NOTE: PrivateIPC=true is intentionally NOT enabled here. +# +# Xwayland (spawned by wlroots inside treeland, IPC-namespace isolated when +# PrivateIPC=true) must share the host IPC namespace with X11 clients so that +# MIT-SHM (XShmAttach → shmat) can find the SysV shared-memory segments the +# clients create via shmget(). Otherwise shmat() fails with EINVAL (segment +# invisible in the private namespace) and every XShmPutImage window renders +# blank. Combined with the cap_ipc_owner setup above, Xwayland can both find +# and attach cross-UID client segments. See Xext/shm.c:ProcShmAttach. +# PrivateIPC=true ProtectSystem=full ProtectHome=true ProtectClock=true