{
  "finding_id": "DF-4884",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Double-free of adev->bios when amdgpu_get_bios() fails: all five live VBIOS read methods kfree(adev->bios) without NULLing it (amdgpu_bios.c:116,145,185,354,428); the probe-failure teardown path amdgpu_kms.c:245 -> amdgpu_device_fini() -> unconditional kfree(adev->bios) (amdgpu_device.c:2762) frees the dangling pointer a second time (adev->rmmio is already mapped at amdgpu_device.c:2473, so the rmmio==NULL bypass is not taken). Deterministic given the precondition (AMD GPU whose VBIOS fails all six read methods: GPU-passthrough VM with garbage ROM BAR, crafted VFCT/ATRM ACPI, disabled ROM shadow). NOT reproduced on the audit guest: it has no AMD PCI device (env.txt: zero vendor-0x1002 devices; only QEMU std-VGA 0x1234), so amdgpu never attaches and the probe path is unreachable by construction. Every hop of the chain is verified by source trace in VERDICT.md; no runtime claim is made beyond that.",
  "exploit_chain": "",
  "evidence": "VERDICT.md (full path:line trace of both frees and the teardown chain); env.txt (guest PCI inventory proving hardware absence); trigger.sh + run.log (precondition check output); fix.diff (git-apply-clean fix, NULLs adev->bios at all 5 live kfree sites)",
  "kernel_refs": [
    "sys/dev/drm/amd/amdgpu/amdgpu_bios.c:116",
    "sys/dev/drm/amd/amdgpu/amdgpu_bios.c:145",
    "sys/dev/drm/amd/amdgpu/amdgpu_bios.c:185",
    "sys/dev/drm/amd/amdgpu/amdgpu_bios.c:354",
    "sys/dev/drm/amd/amdgpu/amdgpu_bios.c:428",
    "sys/dev/drm/amd/amdgpu/amdgpu_bios.c:446",
    "sys/dev/drm/amd/amdgpu/amdgpu_device.c:2473",
    "sys/dev/drm/amd/amdgpu/amdgpu_device.c:2536",
    "sys/dev/drm/amd/amdgpu/amdgpu_device.c:2762",
    "sys/dev/drm/amd/amdgpu/amdgpu_kms.c:99",
    "sys/dev/drm/amd/amdgpu/amdgpu_kms.c:245",
    "sys/dev/drm/amd/amdgpu/cik.c:922",
    "sys/dev/drm/amd/amdgpu/vi.c:406",
    "sys/dev/drm/amd/amdgpu/soc15.c:236"
  ],
  "poc_changes": "n/a \u2014 no seeded PoC code existed; the bug is probe-time and hardware-preconditioned, so the pack carries a precondition checker + exhaustive trace instead of a runnable local trigger",
  "attempts": 1,
  "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": 30,
  "guest_dirty": 0,
  "build_cmd": "none (no AMD hardware on guest; see trigger.sh)",
  "run_cmd": "./trigger.sh",
  "code_hash": "",
  "notes": "Guest has amdgpu.ko available but zero AMD PCI devices; kldstat shows it unloaded. Bug mirrors upstream Linux (same kfree-without-NULL pattern in drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c + unconditional kfree in amdgpu_device_fini). Same-bug family as the known ATRM pair (DF-1950/DF-1951) but a distinct defect: lifetime bug on the failure path, not an ACPI-return-validation bug.",
  "recommended_fix": "Set adev->bios = NULL after every kfree(adev->bios) failure-site in amdgpu_bios.c (5 live sites) so amdgpu_device_fini()s unconditional kfree sees NULL \u2014 see fix.diff",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff verified git-apply --check clean against pristine sys/; correctness by inspection (NULLing breaks the only dangling path; no consumer of adev->bios exists between amdgpu_get_bios() failure and the fini kfree \u2014 amdgpu_atombios_init() is only reached on success at amdgpu_device.c:2542). A/B kernel-build validation impossible on this guest: no AMD hardware to reproduce the baseline.",
  "fix_evidence": "findings/poc/DF-4884/fix.diff (5 hunks, all +adev->bios = NULL)"
}