Package: xserver-xorg-core Version: 2:21.1.24-1 Severity: important Tags: patch upstream fixed-upstream Control: found -1 2:21.1.16-1.3+deb13u3 Control: forwarded -1 https://gitlab.freedesktop.org/xorg/xserver/-/issues/1904
Dear Maintainer, Xorg crashes when a modesetting GPU screen that was added through runtime hotplug is removed again: (EE) Segmentation fault at address 0x0 (EE) Caught signal 11 (Segmentation fault). Server aborting The core dump records SIGABRT, since the server aborts from its signal handler. I hit it with a DisplayLink dock using the DisplayLink driver from Synaptics (evdi plus the proprietary DisplayLinkManager daemon), which adds and removes evdi GPU screens at runtime. The bugs are in the X server, though. The first isn't specific to evdi; the second needs a DRM device with no ID_PATH, which evdi cards are. There are two NULL pointer dereferences on this path: 1. xf86platformAddDevice() calls AddGPUScreen() without setting the EnableDisableFBAccess and SetDGAMode defaults that the boot path in xf86Init.c sets for every GPU screen. xf86CrtcScreenInit() still wraps DGACloseScreen onto the screen, so when the device is removed DGACloseScreen() calls through a NULL SetDGAMode. 2. config_udev_get_fallback_bus_id() passes the parent device's subsystem from udev_device_get_subsystem() to strcmp() unchecked. It runs on remove for DRM devices with no ID_PATH, and the parent's subsystem can already be gone by then. This one is a race: I have a symbolized core dump showing it, but can't trigger it on demand. On my laptop the first one crashed the greeter's X server on nearly every boot with the dock attached (LightDM restarted it). #1143632 may be the same crash as the first bug: there, a udl GPU screen probed at boot is removed cleanly, while one re-added by hotplug segfaults at address 0x0 when removed. That matches the missing SetDGAMode default, but I can't confirm it without that report's log. Both fixes are merged upstream, on main as MR !2244 and !2245, and backported to server-21.1-branch as MR !2302 (merged 2026-09-06): https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2302 431125a2 xfree86: set GPU screen FB/DGA defaults on runtime hotplug 640a9671 config/udev: guard against NULL subsystem in fallback bus id They are in the 26.1 release candidates (26.0.99.901 and .902) but not in any 21.1.x release yet; the backport landed after 21.1.24. The two commits are attached as git format-patch files. Both apply cleanly to 2:21.1.24-1 and to 2:21.1.16-1.3+deb13u3, on top of the existing debian/patches. I wrote both patches. My testing has been on Ubuntu, not Debian. Ubuntu's development series has carried them since 2:21.1.22-1ubuntu4 (https://bugs.launchpad.net/bugs/2160643) and kept them in its 2:21.1.24-1ubuntu1 merge, which built on all architectures. I have run a backport to 21.1.12 on Linux Mint 22.3 with a DisplayLink dock since late June, with no Xorg crashes since. I haven't reproduced the bug on Debian itself. Could you apply them to unstable rather than waiting for the next 21.1.x release? Thanks, Gary T. Giesen
From 431125a21829b80a0c93102252922ffea0f92a7d Mon Sep 17 00:00:00 2001 From: "Gary T. Giesen" <[email protected]> Date: Thu, 25 Jun 2026 14:21:53 -0400 Subject: [PATCH] xfree86: set GPU screen FB/DGA defaults on runtime hotplug When a platform GPU device is added at runtime, xf86platformAddDevice calls AddGPUScreen without first assigning the EnableDisableFBAccess and SetDGAMode function-pointer defaults. The boot path in xf86Init.c sets both of these for every GPU screen before it calls AddGPUScreen, so a screen added by hotplug is left with SetDGAMode == NULL. modesetting's ScreenInit reaches xf86CrtcScreenInit, which wraps DGACloseScreen onto the screen regardless of how the screen was created. When the device is later removed, xf86platformRemoveDevice tears the GPU screen down and DGACloseScreen calls pScrn->SetDGAMode(pScrn, 0, NULL). On a hotplug-added screen that pointer is NULL, so the call faults and takes down the server with a SIGSEGV. This is not DisplayLink-specific: any modesetting platform GPU screen added at runtime and later removed hits it. DisplayLink/evdi just makes it easy to reproduce, because the evdi platform device is added and reconfigured at runtime. Mirror the boot path by assigning the same defaults in xf86platformAddDevice immediately before the AddGPUScreen call. Closes: #1904 Signed-off-by: Gary T. Giesen <[email protected]> (cherry picked from commit dbcd36b38faac64f23006825d6441d9ecec7310a) Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2302> --- hw/xfree86/common/xf86platformBus.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c index 45028f7a6f..4a281bc0f4 100644 --- a/hw/xfree86/common/xf86platformBus.c +++ b/hw/xfree86/common/xf86platformBus.c @@ -659,6 +659,15 @@ xf86platformAddDevice(int index) return -1; } + /* + * Almost everything uses these defaults, and many of those that + * don't, will wrap them. + */ + xf86GPUScreens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess; +#ifdef XFreeXDGA + xf86GPUScreens[i]->SetDGAMode = xf86SetDGAMode; +#endif + scr_index = AddGPUScreen(xf86GPUScreens[i]->ScreenInit, 0, NULL); if (scr_index == -1) { xf86DeleteScreen(xf86GPUScreens[i]); -- GitLab
From 640a967175c8a20484021bccc17cfe93141306c6 Mon Sep 17 00:00:00 2001 From: "Gary T. Giesen" <[email protected]> Date: Fri, 26 Jun 2026 14:56:18 -0400 Subject: [PATCH] config/udev: guard against NULL subsystem in fallback bus id config_udev_get_fallback_bus_id() passes the result of udev_device_get_subsystem() straight into strcmp(). That accessor can return NULL when the device has no subsystem, so strcmp(NULL, "pci") dereferences a NULL pointer and the server crashes with a SIGSEGV. The path is reached for any DRM device with no udev ID_PATH property, where config_udev_odev_setup_attribs() falls back to this function. DisplayLink/evdi virtual cards have no ID_PATH; a udev remove of such a card during teardown can present a parent whose subsystem is already gone (reported NULL), and the unchecked strcmp faults. The same NULL-subsystem-into-strcmp class was fixed for the four sibling callers in this file by commit 429ee86a; config_udev_get_fallback_bus_id() was added later (commit 2f53d1cf) without the guard. The preceding parent==NULL case is already guarded here; extend the same defensiveness to the subsystem lookup. Related to: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1905 Signed-off-by: Gary T. Giesen <[email protected]> (cherry picked from commit 9babe7e7f687b0342c8ab726d01a658d590d7c54) Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2302> --- config/udev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/udev.c b/config/udev.c index 836fc2afa1..db5189a98f 100644 --- a/config/udev.c +++ b/config/udev.c @@ -512,13 +512,15 @@ static char* config_udev_get_fallback_bus_id(struct udev_device *udev_device) { const char *sysname; + const char *subsys; char *busid; udev_device = udev_device_get_parent(udev_device); if (udev_device == NULL) return NULL; - if (strcmp(udev_device_get_subsystem(udev_device), "pci") != 0) + subsys = udev_device_get_subsystem(udev_device); + if (!subsys || strcmp(subsys, "pci") != 0) return NULL; sysname = udev_device_get_sysname(udev_device); -- GitLab

