DF-4855 / verdict.json
{ "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)" } |