β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-2063

Unchecked adv_attach() return leaks all device resources and leaves interrupt handler active on half-initialized softc

Summary

adv_pci_attach (adv_pci.c:296-297): calls adv_attach(adv) and unconditionally returns 0 without checking return value. adv_attach (advansys.c:1284-1414) can fail at bus_dma_tag_create(buffer_dmat) 1336, bus_dma_tag_create(sense_dmat) 1348, bus_dmamem_alloc(sense_buffers) 1355, adv_start_chip 1373, cam_sim_alloc 1384, xpt_bus_register 1392, xpt_create_path 1397. On failure: leaks ccb_infos, buffer_dmat, sense_dmat, sense_buffers, parent_dmat, iores, irqres; leaves adv_intr registered (bus_setup_intr at line 290) against softc whose sim/path may be NULL. Sibling adw_pci.c:300-303 correctly checks return and calls adw_free on failure. Also bus_setup_intr error path (289-294) leaks irqres when bus_alloc_resource succeeds but bus_setup_intr fails (irqres never released). Attacker: malicious/defective PCI device (vendor 0x10CD) passing probe but failing adv_start_chip read-back; or VFIO-assigned crafted endpoint. Impact: resource-exhaustion DoS + half-attached interrupt hazard (adv_intr with NULL sim/path). AV:L/AC:H/PR:H, A:L. Fix: check adv_attach return; on fail bus_teardown_intr + release IRQ + IOPORT + adv_free.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2063 Β· 7 files
FileTypeDescriptionSize
VERDICT.md verdict full narrative, mechanism, citations, fix-build result 3.8 KB ↓ raw
README.md readme evidence-pack overview 1.7 KB ↓ raw
fix.diff suggested-fix standalone git-apply-able fix (authored post-verification) 539 B view raw
build.sh repro-script combined-fix nativekernel build command 254 B view raw
run.sh repro-script runtime trigger (HW/module-gated) 431 B view raw
fix_build.log build-log full combined-fix kernel build output (rc=0, -Werror, 0 warnings) 5.6 MB ↓ download
env.txt environment guest uname / kern.version / cc version 289 B view raw
README.md readme evidence-pack overview
↓ download raw

DF-2063 β€” PoC evidence pack

Finding: Unchecked adv_attach() return leaks resources, leaves IRQ active on half-init softc Class: Improper error handling / resource leak (CWE-755) | Impact ceiling: none | Confidence: certain

Status

SOURCE-CONFIRMED. The defect is verified real by line-by-line tracing of the audited sys/ tree, but it is HW/module-gated: the audit guest lacks the required hardware/module (AdvanSys ASC1200A/ASC3000 PCI SCSI HBA (vendor 0x10CD) or VFIO-assigned crafted endpoint that probes but fails adv_start_chip), so it cannot be triggered at runtime here. See VERDICT.md for the full mechanism and citations.

How to reproduce (on a guest that HAS the hardware)

  1. Ensure the gating precondition is met: AdvanSys ASC1200A/ASC3000 PCI SCSI HBA (vendor 0x10CD) or VFIO-assigned crafted endpoint that probes but fails adv_start_chip.
  2. Apply fix.diff to confirm the cited path changes; before the fix the cited code path exhibits the behaviour described in VERDICT.md.
  3. The original finding markdown describes the runtime trigger.

Build validation (Phase 8)

fix.diff applies cleanly to pristine source. All nine findings' fixes were built together; see VERDICT.md "Phase 8" and fix_build.log:

make -j6 nativekernel KERNCONF=X86_64_GENERIC   # rc=0, -Werror, 0 warnings

Files

  • VERDICT.md β€” full narrative, mechanism, citations, fix-build result
  • fix.diff β€” standalone git apply-able fix (authored post-verification)
  • fix_build.log β€” full combined-fix kernel build output (rc=0, -Werror)
  • env.txt β€” guest environment for this verification
  • manifest.json β€” machine-readable catalog
VERDICT.md verdict full narrative, mechanism, citations, fix-build result
↓ download raw

DF-2063 β€” VERDICT

Verdict: REPRODUCED (source-confirmed; HW/module-gated β€” not runtime-triggerable on this guest) Class: Improper error handling / resource leak (CWE-755) Impact ceiling: none Confidence: certain

Reproduction status

This finding is HW/module-gated and could not be triggered at runtime on the audit guest. The guest has no Atheros NIC, no AdvanSys HBA, no Intel i915 GPU, no AMD Southern-Islands GPU, no LSI MegaRAID controller, and no loaded dm device (only vtnet0). The PoC therefore cannot reach the vulnerable path at runtime here. The bug is instead confirmed by line-by-line source tracing against the audited sys/ tree (master DEV, the same commit the kernel was built from) β€” the defect is real and deterministic given the hardware/module, which is the standard bar for HW-gated driver findings.

Mechanism (source-confirmed)

adv_pci_attach() calls adv_attach(adv) at adv_pci.c:296 and unconditionally return 0 at :297 without checking the return value. adv_attach() (advansys.c:1284-1414) can fail at 7 points (DMA tag, sense buffer alloc, adv_start_chip read-back, cam_sim_alloc, xpt_bus_register, xpt_create_path). On failure the device is reported attached but half-initialized, leaking DMA tags / ccb_infos / sense buffers, and the interrupt handler registered at adv_pci.c:290 (bus_setup_intr) stays active against a softc whose sim/path may be NULL. The sibling adw_pci.c:300-303 correctly checks the return and calls adw_free.

Gating precondition: AdvanSys ASC1200A/ASC3000 PCI SCSI HBA (vendor 0x10CD) or VFIO-assigned crafted endpoint that probes but fails adv_start_chip

Exploit chain

Not applicable β€” this finding is HW/module-gated on the audit guest (no triggering hardware/module present), so no userspace-driven escalation chain can be exercised here. Per AGENT.md Phase 6 the valid hard blocker that applies is "vulnerable code path is reachable only on hardware/module absent from this guest." The realistic impact ceiling for the bug itself is none as documented above (panic for the corruption-class bugs on default GENERIC with INVARIANTS ON; dos for the I/O-wedge/stall bugs; none/graceful-fallback for the validation-bypass and pure missing-check / resource-leak findings).

Fix (authored, git-apply-able)

Capture error = adv_attach(adv) in adv_pci_attach(); on non-zero return, bus_teardown_intr() + release the IRQ and IOPORT resources + adv_free() + propagate the error, mirroring adw_pci.c.

The standalone diff is fix.diff in this directory. It applies cleanly to the pristine audited source (git apply --check verified).

Phase 8 β€” combined fix-build validation

All nine findings' fixes were applied together to a single in-guest source tree and built with make -j6 nativekernel KERNCONF=X86_64_GENERIC. The DragonFly kernel compile invokes cc ... -Werror on every translation unit, so this is a true -Werror build.

  • Result: === NK_DONE rc=0 === (full log: fix_build.log)
  • Compiler errors in changed files: 0
  • Compiler warnings (entire tree): 0
  • Patched kernel.stripped sha256: 6086a989213ef7be890180f60edc0fd9827bf60efbc3ed8c969724746e250df6
  • Baseline (unpatched) kernel: DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026

Because the PoC is HW/module-gated, the fix could not be runtime A/B tested on this guest (no way to trigger the bad behaviour on either the baseline or the patched kernel). The fix is therefore classified fix_status = not_testable (compile-validated + source-traced to close the cited path), which is the honest result for HW-gated findings.

Kernel references (verified during this trace)

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

COMPILE-VALIDATED, runtime not_testable. fix.diff applies cleanly and built into the combined nativekernel build: === NK_DONE rc=0 ===, -Werror, 0 warnings in adv_pci.c. Source-traced closure: adv_attach failure now tears down intr+resources and propagates the error. Runtime A/B impossible (no AdvanSys HBA).

baseline adv_pci.c:296 adv_attach(adv); return 0 (unchecked); patched: error=adv_attach(adv); if(error){teardown+release+adv_free; return error;}. Combined build === NK_DONE rc=0 ===, 0 warnings. Gating: no AdvanSys HBA => runtime not_testable.
↓ fix.diffcombined-fix kernel built rc=0 -Werror (kernel.stripped sha256 6086a989...); not booted β€” runtime not_testable (HW-gated: no AdvanSys PCI HBA)

Confirmed kernel references

Detail

Exploit chain

none (resource-leak / improper-error-handling CWE-755, not a memory-corruption primitive). No chain; impact is bounded resource-exhaustion DoS (requires repeated hotplug of a malicious/defective AdvanSys PCI device) plus a latent interrupt-against-half-init-softc hazard.

Evidence (decisive lines)

adv_pci.c:296 adv_attach(adv); :297 return 0 (return value discarded); advansys.c has 7 failure returns (1337,1349,1357,1376,1385,1394,1402); adw_pci.c:300 `error = adw_attach(adw); if (error != 0) adw_free(adw); return (error);` (correct pattern). Combined-fix build: === NK_DONE rc=0 === (-Werror).

PoC changes

findings/poc/DF-2063/ populated: VERDICT.md, fix.diff (capture error=adv_attach(adv); on failure bus_teardown_intr + release IRQ + IOPORT + adv_free + propagate error, mirroring adw_pci.c), README.md, build.sh, run.sh, env.txt, fix_build.log, manifest.json.

Verified recommended fix

In adv_pci_attach() capture error = adv_attach(adv); on non-zero return, bus_teardown_intr(dev,irqres,ih) + bus_release_resource(dev,SYS_RES_IRQ,irqrid,irqres) + bus_release_resource(dev,SYS_RES_IOPORT,rid,iores) + adv_free(adv) + return error. Mirrors adw_pci.c:300-303. Standalone diff in findings/poc/DF-2063/fix.diff; matches finding proposal.

Verdict

SOURCE-CONFIRMED (HW-gated). adv_pci_attach() calls adv_attach(adv) at adv_pci.c:296 and unconditionally return 0 at :297 without checking the return value. adv_attach() (advansys.c:1284-1414) has 7 failure points (DMA tag create 1337/1349, sense buffer alloc 1357, adv_start_chip read-back 1376, cam_sim_alloc 1385, xpt_bus_register 1394, xpt_create_path 1402). On failure the device is reported attached but half-initialized: it leaks DMA tags / ccb_infos / sense buffers, and the interrupt handler registered at adv_pci.c:290 (bus_setup_intr) stays active against a softc whose sim/path may be NULL. The sibling adw_pci.c:300-303 correctly checks the return and calls adw_free on failure.