DF-4452 / verdict.json
{ "finding_id": "DF-4452", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "Wild OOB read in acpi_pci_link_choose_irq(): _PRS extended-IRQ values (raw UINT32, stored unbounded at acpi_pci_link.c:358-367) are used as an index into the 256-entry pci_link_interrupt_weights[] array at acpi_pci_link.c:1015, and the FADT SciInterrupt (16-bit) indexes it unguarded at :1027-1028. PCI_INTERRUPT_VALID is only != 255 (sys/bus/pci/pcivar.h:335), so values >= 256 (or negative via signed conversion) pass every gate. Could not be exercised at runtime on this guest because reaching choose_irq() requires a _PRT entry referencing the crafted link, the guests _PRT lives in QEMUs built-in DSDT, and an injected SSDT cannot redefine an existing namespace name (the SSDT load would be rejected wholesale); this DragonFly tree has no loader DSDT-override support (no acpi_dsdt tunable in sys/boot). Code trace is complete: a value like 0x7FFFFFF0 computes a non-canonical address and faults the kernel during PCI routing (boot DoS); moderate values leak adjacent .bss content only into a weight comparison and, under bootverbose, a console print. Not a false positive: the defect is visible by inspection with exact line citations; it is simply not runtime-injectable on this guests fixed QEMU DSDT.", "exploit_chain": "", "evidence": "README.md (root-cause citations), fix.diff (bounds guards at choose_irq loop + SCI fallback). Key lines: acpi_pci_link.c:125 (array [256]), :358-367 (unbounded ingest), :1010-1019 (OOB index), :1026-1028 (unbounded SCI index), sys/bus/pci/pcivar.h:334-335 (VALID = != 255).", "kernel_refs": [ "sys/dev/acpica/acpi_pci_link.c:125", "sys/dev/acpica/acpi_pci_link.c:358", "sys/dev/acpica/acpi_pci_link.c:1015", "sys/dev/acpica/acpi_pci_link.c:1027", "sys/bus/pci/pcivar.h:335" ], "poc_changes": "No runnable PoC produced: SSDT-based injection (the DF-4451 technique) cannot reach choose_irq() because the path requires a _PRT source reference and the guests PRT is owned by QEMUs DSDT (SSDT redefinition = namespace collision).", "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": 0, "guest_dirty": 0, "build_cmd": "", "run_cmd": "", "code_hash": "", "notes": "Reached only via acpi_pcib_route_interrupt (sys/dev/acpica/acpi_pcib.c:285) for a _PRT-referenced link with an unrouted state and no tunable/BIOS/_CRS initial IRQ. Crafted-DSDT threat bar (same as DF-2389). Fix validated by inspection only (guards included in the DF-4451 fix build which compiles clean).", "recommended_fix": "Reject _PRS IRQ values outside [0, NUM_ACPI_INTERRUPTS) at ingest and bound the SciInterrupt index before pci_link_interrupt_weights[] reads (see fix.diff).", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "Fix guards are part of the DF-4451 fix.diff and compile in the validated NOINV4451 kernel build, but the runtime trigger (PRT-referenced link) cannot be injected on this guest, so no baseline/patched runtime comparison was possible.", "fix_evidence": "findings/poc/DF-4452/fix.diff; DF-4451 fix_build.log shows the same patched file compiling into NOINV4451." } |