Dear Debian X Strike Force,
## Environment
- Distribution: Debian Trixie 13.5
- Kernel: 6.12.90+deb13.1-amd64
- Motherboard: Wistron JIG31B3 (Fujitsu OEM, Intel G31 chipset)
- BIOS: Fujitsu / Phoenix Technologies 3.06 (02/22/2010)
- CPU: Intel Core 2 Duo E6320 @ 1.86GHz
- GPU: Intel 82G31 integrated graphics, PCI ID 8086:29c2, kernel driver i915
- xserver-xorg-core: 2:21.1.16-1.3+deb13u2
- xserver-xorg-video-intel: 2:2.99.917+git20210115-1
- libpciaccess0: 0.17-3+b3
Kernel-side VGA arbiter works correctly: `vgaarb` module is loaded, the Intel G31 GPU is properly registered as the boot VGA device, and the i915 DRM driver initializes without errors (confirmed in dmesg). All hardware and kernel layers are functional; the crash originates purely from userspace libpciaccess logic.
## Reproduction Steps
1. Boot into LightDM Xorg session with the intel video driver loaded
2. Run command over SSH or local terminal:
`sudo -E DISPLAY=:0 XAUTHORITY=/var/run/lightdm/root/:0 xset dpms force off`
3. Xorg crashes immediately with SIGSEGV, drops back to LightDM login manager, all desktop applications terminate.
## Crash Backtrace (intel driver runtime DPMS crash, /var/log/Xorg.0.log)
[ 4975.118] (EE) Backtrace:
[ 4975.118] (EE) 0: /usr/lib/xorg/Xorg (OsSigHandler+0x2d)
[ 4975.121] (EE) 2: /lib/x86_64-linux-gnu/libpciaccess.so.0 (pci_device_vgaarb_set_target+0x113)
[ 4975.122] (EE) 3: /usr/lib/xorg/Xorg (xf86VGAarbiterLock+0x20)
[ 4975.122] (EE) 4: /usr/lib/xorg/Xorg (xf86DPMS+0x38)
[ 4975.123] (EE) 5: /usr/lib/xorg/Xorg (DPMSSet+0x66)
[ 4975.127] (EE) Segmentation fault at address 0x30
## Live GDB Debug Result (attached to running Xorg process)
#0 0x00007f35d71049b3 in pci_device_vgaarb_set_target (dev=0x55b4da995fd0)
at ../../src/common_vgaarb.c:235
(gdb) print pci_sys
$1 = (struct pci_system *) 0x0
(gdb) print dev
$2 = (struct pci_device *) 0x55b4da995fd0
The `dev` pointer is fully valid and its members are readable; only the global `pci_sys` pointer is NULL when entering the function.
## Additional modesetting-only driver test result
After purging `xserver-xorg-video-intel` to remove the intel DDX driver, Xorg loads only the generic modesetting driver. However, X still crashes during early output initialization with a different segfault, proving the bug affects all VGA arbiter functions in libpciaccess, not only `pci_device_vgaarb_set_target`:
(EE) Backtrace:
(EE) 0: /usr/lib/xorg/Xorg (OsSigHandler+0x2d)
(EE) 2: /lib/x86_64-linux-gnu/libpciaccess.so.0 (pci_device_vgaarb_unlock+0x25)
(EE) 3: /usr/lib/xorg/Xorg (InitOutput+0x9a1)
(EE) Segmentation fault at address 0x28
GDB confirms the identical root cause: global `pci_sys` remains NULL inside `pci_device_vgaarb_unlock`.
## Root Cause
All VGA arbiter helper functions in `src/common_vgaarb.c` fail to validate the global `pci_sys` pointer before dereferencing its members.
For `pci_device_vgaarb_set_target`:
1. DPMS state change triggers xf86DPMS → xf86VGAarbiterLock → pci_device_vgaarb_set_target
2. The input `dev` pointer is non-NULL, so the existing `if (!dev)` check is skipped entirely
3. The code directly accesses `pci_sys->vgaarb_fd`, `pci_sys->vga_count`, and `pci_sys->vga_target` without any NULL guard
4. On this vintage G31 hardware, userspace PCI initialization does not populate `pci_sys`, leaving it NULL. Dereferencing memory offset 0x30 triggers the SIGSEGV.
This is an independent userspace logic flaw inside libpciaccess; any kernel-level vgaarb configuration cannot resolve the NULL pointer dereference.
## Proposed Fix
Add a NULL check for `pci_sys` at the entry of every vgaarb helper function. The minimal patch for `pci_device_vgaarb_set_target` is shown below:
int
pci_device_vgaarb_set_target(struct pci_device *dev)
{
int len;
char buf[BUFSIZE + 1];
int ret;
/* Fix: avoid NULL dereference when PCI system is uninitialized */
if (!pci_sys)
return -1;
if (!dev)
dev = pci_sys->vga_default_dev;
if (!dev)
return -1;
/* rest of original code unchanged */
}
The same `if (!pci_sys)` guard should be added to `pci_device_vgaarb_lock`, `pci_device_vgaarb_unlock` and so on to fix the modesetting initialization crash.
## Verified Workarounds
1. Permanent stable workaround: Disable DPMS X extension via xorg.conf
Create /etc/X11/xorg.conf.d/90-nodpms.conf:
Section "ServerFlags"
Option "DPMS" "false"
EndSection
Section "Device"
Identifier "IntelGPU"
Driver "intel"
Option "DPMS" "off"
EndSection
Restart LightDM/Xorg. The DPMS extension is fully removed from the X server, so no vgaarb libpciaccess functions are invoked at any stage, eliminating all segfaults.
Important note: Running `xset -dpms` on a live running X session instantly crashes the server and cannot be used as a temporary runtime fix. Simple `xset s off` only modifies screensaver timeout and does not block DPMS code paths.
2. Partial incomplete workaround: Remove xserver-xorg-video-intel to use modesetting driver
This avoids runtime DPMS-triggered crashes but still hits a segfault during X initialization via pci_device_vgaarb_unlock. Not recommended for stable daily use.
## Ineffective Attempts (no crash mitigation at all)
1. Xorg ServerFlags: Option "NoVGAARB" "true"
2. Intel driver device option: Option "VGAARB" "off"
3. Kernel boot parameter vgaarb.disabled=1 + blacklist vgaarb module
All three options only modify kernel VGA arbiter behavior and do not touch the userspace NULL pointer logic in libpciaccess. The segmentation fault still reproduces reliably.
## Attached Files List
1. hardware_report.txt: Full hardware DMI, PCI, kernel module, dmesg and package version report
2. Xorg-intel-dpms-crash.log: Xorg crash log with backtrace for intel driver DPMS trigger
3. Xorg-modesetting-init-crash.log: Xorg early initialization segfault log with pure modesetting driver
4. common_vgaarb.c: Unmodified source file from libpciaccess 0.17-3+b3 containing all faulty vgaarb functions
Please let me know if core dumps, additional GDB traces or test builds are required for further debugging.
Regards,
euughost