⬢ DragonFlyBSD Kernel Audit
DF-4855 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4855",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Code defect is certain by line trace: agp_amd64_attach calls agp_generic_attach (agp.c:196) which make_dev()s /dev/agpgart at agp.c:240-242, then three vendor set_aperture failures (agp_amd64.c:207-208 ULi, :213-214 nVidia, :221-223 VIA) return ENXIO with no unwind - newbus never calls detach for a failed attach, so the GATT contigmalloc (up to 2MiB, agp.c:146), the aperture bus resource and the live 0600 /dev/agpgart node on an unattached device all leak. Trigger is hardware-gated (ULi M1689 with >=512MB or nForce3 with >=1GB BIOS-set aperture, since the vendor sub-tables at agp_amd64.c:398-406/:433-441 reject those sizes that the host table :265-273 accepts); the ioctl surface is root-only (0600). Runtime reproduction was impossible on the audit guest: QEMU i440FX presents only host bridge 0x12378086, which matches no id in agp_amd64_match (agp_amd64.c:87-112), so the driver never attaches - trigger builds clean and open() returns ENOENT for root and nobody. No memory-safety violation in the driver itself: the orphaned-node binds write in-bounds into a GATT that is allocated (sc->gatt set at :202) but never installed (ATTBASE/GARTEN loop :229-238 never ran), so impact is resource leak + stale-cdev functional corruption, Low.",
  "exploit_chain": "",
  "evidence": "VERDICT.md (line-trace + trigger conditions); run.log (guest: ENOENT root+nobody, single host bridge 0x12378086, agp in-kernel but /dev/agpgart absent); fix.diff (git-apply-able unwind, validated with git apply --check)",
  "kernel_refs": [
    "sys/dev/agp/agp_amd64.c:183",
    "sys/dev/agp/agp_amd64.c:202",
    "sys/dev/agp/agp_amd64.c:207-208",
    "sys/dev/agp/agp_amd64.c:213-214",
    "sys/dev/agp/agp.c:240-242",
    "sys/dev/agp/agp_amd64.c:221-223",
    "sys/dev/agp/agp_amd64.c:229-238"
  ],
  "poc_changes": "agp_bind field corrected for DragonFly sys/sys/agpio.h:149-152 (pg_start, not offset); guest heredoc re-formatting",
  "attempts": 2,
  "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": 140,
  "guest_dirty": 0,
  "build_cmd": "cc -O -o agp_orphan agp_orphan.c",
  "run_cmd": "/tmp/df4855/agp_orphan (root); su -m nobody -c /tmp/df4855/agp_orphan",
  "code_hash": "864a8fbe117660ebb47af0b9fe5a46b53ad90ba2e4149b0551d9c354b328a3b4",
  "notes": "Hardware absent on guest (single i440FX host bridge; no AMD64-AGP chipset ids) - not_reproduced is a hardware-gated negative, not a refutation; static proof is complete. Same class as DF-1986 (agp_via.c:180-183, Low). Recommended systemic hardening: move make_dev out of agp_generic_attach or reject unattached devices in agp_open/agp_ioctl (agp.c).",
  "recommended_fix": "Convert the three vendor set_aperture failures in agp_amd64_attach to goto err; unwind with agp_free_gatt(sc->gatt) + agp_generic_detach(dev); see fix.diff",
  "fix_status": "not_applicable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff is a compile-pattern-correct unwind authored against the read-only tree and validated with git apply --check; kernel build validation is hardware-gated (attach cannot be exercised on the QEMU guest with or without the fix)",
  "fix_evidence": "fix.diff (git apply --check OK)"
}