⬢ DragonFlyBSD Kernel Audit
DF-4678 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4678",
  "status": "untested",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "runtime_sec": 0,
  "guest_dirty": 0,
  "build_cmd": "",
  "run_cmd": "",
  "code_hash": "",
  "verdict": "NOT TESTED ON THE GUEST (status untested): this QEMU guest has no Intel graphics device, so the i915 attach path and the DragonFly devm_request_mem_region shim (i915_gem_stolen.c:83-104) cannot execute there; the finding is a source-audit fact verified line-by-line against the guests /usr/src copy (md5 match, see env.txt). FACTS (certain): (1) the shims private static struct rman stolen_rman is invisible to every other driver and to the kernels physical-memory bookkeeping, and rman_manage_region (subr_rman.c:123-150) performs no overlap check (NB: this interface is not robust ... multiple copies) -- therefore i915_adjust_stolens conflict detection (i915_gem_stolen.c:156-188), whose entire purpose is to refuse stolen use (something is seriously wrong) when the range is already owned, is VACUOUS on DragonFly: devm_request_mem_region returns non-NULL unconditionally except on ENOMEM, the -EBUSY path at :182-187 is dead code, and the GEN3 apparently this works carve-out is meaningless. (2) DF also does not carve stolen out of phys_avail at early boot (the phys_avail_reserve() call in sys/bus/pci/x86_64/pci_early_quirks.c:310-312 is commented out XXX: enable this once the KPI is available), so on firmware that leaves the stolen range inside e820-RAM, nothing prevents the kernel page allocator and the i915 stolen allocator from owning the same physical pages -- silent cross-corruption of kernel memory by GPU DMA (the exact double-ownership scenario the removed check exists to catch; upstream Linux guards it with e820 reservation + the real devm_request_mem_region). (3) Latent shim defects: rm_end = start + n manages one extra page (rman ranges are inclusive, subr_rman.c convention); a second call re-runs rman_init on the live static rman, re-inserting it into the global rman_head and leaking the old rm_slock (subr_rman.c:87-116); the kmallocd res is never freed. SECURITY IMPACT: config/firmware-gated (needs a BIOS that leaves stolen inside RAM -- no unprivileged trigger); consequence is silent kernel-memory corruption on such machines, so impact is framed as none-from-unprivileged / corruption-on-affected-firmware. fix.diff repairs the shim internals (one-time rman init, inclusive end, wrapped/empty-range refusal) but honest framing: true conflict detection requires kernel KPI the shim does not have; the durable fix is reserving stolen from phys_avail at early boot (pci_early_quirks.c) -- cross-referenced, out of this files scope.",
  "exploit_chain": "buggy BIOS reports stolen inside e820-RAM -> DF never reserves it from phys_avail (pci_early_quirks.c:310-312 XXX) AND i915_adjust_stolens devm_request_mem_region cannot detect the conflict (shim always succeeds) -> kernel page allocator and i915 stolen objects own the same physical pages -> GPU DMA over live kernel memory. No unprivileged trigger; no uid0 route; not demonstrable on this guest (no i915 hardware).",
  "evidence": "Source citations in VERDICT.md: i915_gem_stolen.c:83-104 (shim), :156-188 (dead conflict path), :175-177 (retry with resource_size(dsm)-2 underflow when size<2); subr_rman.c:87-150 (no overlap check, inclusive ranges, rman_head re-insert); pci_early_quirks.c:56,303-312 (stolen detection + commented-out reservation); env.txt (guest /usr/src md5 match).",
  "kernel_refs": [
    "sys/dev/drm/i915/i915_gem_stolen.c:83-104",
    "sys/dev/drm/i915/i915_gem_stolen.c:156-188",
    "sys/dev/drm/i915/i915_gem_stolen.c:175-177",
    "sys/kern/subr_rman.c:87-116",
    "sys/kern/subr_rman.c:123-150",
    "sys/bus/pci/x86_64/pci_early_quirks.c:296-313"
  ],
  "poc_changes": "No PoC runnable: guest lacks Intel graphics. Analysis-only pack; code path cited line-by-line against the guests own /usr/src (md5-verified).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff repairs the shims internal defects (single rman_init guarded by a static flag, inclusive rm_end, refusal of n==0 or wrapped ranges) and is git-apply-able against the pristine tree, but the fix cannot be exercised on this guest: the i915 device never attaches under QEMU and the shim is kernel-KPI-dependent (rman), so no userspace harness can faithfully run it. fix_status=not_testable for lack of hardware, not for doubt in the change; a full validation needs any physical G4X+/ILK/BDW+ Intel-gfx DragonFly machine.",
  "fix_evidence": "fix.diff in pack (git apply --check clean against sys/); source citations above.",
  "attempts": 0,
  "notes": "Filed Low despite silent-corruption potential because the trigger is firmware-config-only (no unprivileged path); on affected firmware the kernel/GPU double-ownership is silent and catastrophic -- the triage team may want to raise it once pci_early_quirks.cs phys_avail_reserve gap is tracked (pass 1 marked that file clean; cross-reference only, not re-filed here). DF-1712 (unzeroed stolen fbdev, intel_fbdev.c) is a separate manifestation of DFs stolen-handling gap and was NOT re-reported.",
  "recommended_fix": "Repair the shim (one-time rman init, inclusive bounds, wrapped-range refusal) and, upstream of it, reserve the stolen range from phys_avail at early boot so the page allocator can never hand out stolen pages (fix.diff + pci_early_quirks.c cross-ref)."
}