DF-4818 / verdict.json
{ "finding_id": "DF-4818", "status": "inconclusive", "reproduced": 0, "impact": "panic", "confidence": "certain", "verdict": "Code-certain defect, panic not forceable on the emulator. nvme_pci_attach() never checks the return of bus_alloc_resource_any() for MSI-X vector IRQs (nvme_attach.c:166-168) and validates only sc->irq[0] (:239); a NULL sc->irq[k>=1] propagates to bus_setup_intr in nvme_create_comqueue (nvme.c:823) and panics unconditionally in nexus_setup_intr (nexus.c:505-506), or into bus_release_resource in the attach unwind (nvme_attach.c:193-199) and panics in resource_list_release (subr_bus.c:2738-2739); additionally the MSI-X->legacy fallback never calls pci_teardown_msix after a successful pci_setup_msix, leaving msix_table_res set so a re-attach KASSERT-panics on INVARIANTS kernels (pci.c:1644-1645) \u2014 the audit GENERIC runs INVARIANTS. Live on the guest every *reachable* sub-path was exercised and proven safe: baseline 7-vector MSIX attach; empty-MSI-pool i=0 failure with clean legacy fallback (disk attaches); and a forced mid-loop vector failure (24 controllers, pool 64 vs 72 demanded) where the unwind loop released a live allocated vector, fell back, and the disk attached \u2014 no nvme panic. This brackets the defect to exactly the unchecked NULL, whose trigger (rman_reserve_resource failure on a freshly granted MSI-X irq = kernel-memory pressure/desync) cannot be induced from QEMU config or loader tunables. Expected impact if triggered: boot/driver-load-time kernel panic (DoS, no unprivileged trigger path).", "exploit_chain": "", "evidence": "README.md and VERDICT.md (full path proof with path:line); run.log (baseline: nvme0: mapped 7 MSIX IRQs); run.2.log (empty pool: nvme0: mapped 1 normal-int IRQs, disk attaches); run.3.log (mid-loop: nvme0-20 mapped 3 MSIX IRQs, nvme21/22/23 fallback after unwind executed with an allocated vector, disks attach); panic.txt (INCIDENTAL: live-reproduced vtpci/vtnet panic MSI-X is not setup yet \u2014 different driver, surfaced for separate audit; also proves the guest kernel runs INVARIANTS); fix.diff (checks the alloc, tears MSI-X down on fallback).", "kernel_refs": [ "sys/dev/disk/nvme/nvme_attach.c:166", "sys/dev/disk/nvme/nvme_attach.c:239", "sys/dev/disk/nvme/nvme_attach.c:193", "sys/dev/disk/nvme/nvme_attach.c:225", "sys/dev/disk/nvme/nvme.c:823", "sys/platform/pc64/x86_64/nexus.c:505", "sys/kern/subr_bus.c:2738", "sys/bus/pci/pci.c:1644" ], "poc_changes": "No seed PoC existed. The trigger is a kernel-internal resource-allocation failure, so the evidence pack is a three-phase QEMU experiment driver (run.sh + dfbsd-qemu/vm_nvme24.sh) using the hw.ioapic.msi_start loader tunable to pressure the per-cpu MSI-X pool, rather than a C program.", "attempts": 3, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly v6.5.0.1712.g89e6a-DEVELOPMENT #1: Mon Jun 29 14:18:01 UTC 2026 root@ephemeral-5c2002c44b6c:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 1500, "guest_dirty": 0, "build_cmd": "(nothing to build \u2014 config-driven trigger; ./build.sh documents this)", "run_cmd": "findings/poc/DF-4818/run.sh (phases: baseline / emptypool / midloop)", "code_hash": "f74e47d3d6475562fa7bab8939d36dad1edee392ba2b1fe4658b9c8c89ec13a3", "notes": "INCIDENTAL LIVE DISCOVERY for the orchestrator (NOT part of this findings files): sys/dev/virtual/virtio/virtio_pci.c vtpci_intr_release() panics (MSI-X is not setup yet, KASSERT sys/bus/pci/pci.c:1588-1590) on the vtnet attach-error path whenever the MSI-X pool is exhausted \u2014 reproduced on every pool-pressure boot (panic.txt, run.2.log, run.3.log). Recommend a dedicated audit spawn for virtio_pci.c. Guest left reverted to the clean-install snapshot.", "recommended_fix": "Check bus_alloc_resource_anys return in the MSI-X vector loop and fail the MSI-X attempt on NULL; call pci_teardown_msix() on the MSI-X->legacy fallback when pci_setup_msix had succeeded (fix.diff).", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "Fix validation not possible: the panic precondition (bus_alloc_resource_any returning NULL for a granted MSI-X vector) cannot be induced on the emulator, so no baseline bad behavior exists to diff a patched kernel against. The fix is a straightforward guard + teardown whose correctness follows from the code paths exercised live (unwind and fallback already work correctly for pci_alloc_msix_vector failures).", "fix_evidence": "fix.diff (unified, git-apply-able, authored against the read-only sys/ tree; never applied)" } |