DF-2223 / verdict.json
{ "finding_id": "DF-2223", "status": "reproduced", "reproduced": 1, "impact": "denial_of_service", "confidence": "certain", "verdict": "Reproduced mechanically on 7 REAL guest PCI devices through the fully real code path: the verbatim pcie_capability_read_dword, the real pcie_capability_reg_implemented predicate chain (real pci_is_pcie ivar reads, real config-space access helpers), with only struct pci_dev fabricated as a zeroed wrapper whose dev.bsddev points at the real device_t. On every device the baseline function returns -EINVAL for PCI_EXP_LNKCAP while leaving *dst completely untouched (stack canary 0xa5a5a5a5 intact) - the exact contract divergence from upstream Linux (*val = 0 before the error return). The consumer emulation mirroring the real pcie_get_width_cap inline (linux/pci.h:608-617, return value ignored) then derives width 0x1a from the uninitialized stack word; the fixed variant writes *dst = 0 giving the deterministic PCIE_LNK_WIDTH_UNKNOWN. No userspace info leak (the garbage bits are masked before use); realistic ceiling is driver misbehavior / wrong register programming on hardware where the predicate is false (non-PCIe devices, or PCIe v1 non-endpoint/root devices per the finding), a local DoS / incorrect-driver-behavior class. No corruption or write primitive, no privesc chain. Fix validated A/B in the same kernel.", "exploit_chain": "", "evidence": "run.log lines DF2223 BASELINE/FIXED per device (hostb0, isab1, atapci0, none0, vgapci0, virtio_pci0, virtio_pci1): baseline rc=-22 dst=0xa5a5a5a5 UNTOUCHED-CANARY on all 7, consumer width=0x1a from uninit stack; FIXED rc=-22 dst=0x00000000, consumer width=0xff deterministic", "kernel_refs": ["sys/dev/drm/linux_pci.c:35", "sys/dev/drm/linux_pci.c:36", "sys/dev/drm/include/linux/pci.h:473", "sys/dev/drm/include/linux/pci.h:475", "sys/dev/drm/include/linux/pci.h:445", "sys/dev/drm/include/linux/pci.h:608", "sys/dev/drm/include/linux/pci.h:612"], "poc_changes": "Rebuilt as verbatim-code kernel-compiled rig; replaced the PoC sketch idea of a purely fabricated pci_dev with a zeroed struct pci_dev wrapping each real guest device_t so the predicate chain and config reads are entirely real; stack-canary instrumentation around *dst", "attempts": 2, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Tue Oct 20 23:24:18 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/DFV22X x86_64", "runtime_sec": 15, "guest_dirty": 0, "build_cmd": "sh /root/poc/df22x/build.sh (nativekernel KERNCONF=DFV22X, rig compiled kernel-resident)", "run_cmd": "sh /root/poc/df22x/run.sh (sysctl kern.df22x_run=1 as root on the DFV22X harness kernel)", "code_hash": "c646506a8cbeda4dcb0ade737617a507fac86cf3d381b7df14e25aad5ab10fae", "notes": "Batch verification run with DF-2216/2220/2224; guest reset with-src before return. The amdgpu call sites cited by the finding (pcie_get_width_cap consumers amdgpu_device.c:3550, cik.c:1634) need AMD hardware absent on this guest; the divergence itself is proven on real devices. The implemented-path control (PCI_EXP_FLAGS_TYPE) also returns -EINVAL on this guest because the predicate first checks pci_is_pcie and every i440fx device is classic PCI - honestly noted in the log lines", "recommended_fix": "Zero *dst before returning -EINVAL on the register-not-implemented path, matching the upstream LinuxKPI contract consumers expect (see fix.diff)", "fix_status": "fixed", "fix_validated": 1, "fix_diff": "fix.diff" } |