Stale base pointer in isp_pci_mbxdma error cleanup causes kernel-heap multi-free
Summary
isp_pci_mbxdma() uses single local caddr_t base for both control-area allocation and every per-channel FC scratch allocation. FC scratch loop overwrites base on each iteration. When any later step fails (most reachable: bus_dmamap_create ENOMEM in per-command map loop ~256 maps) control reaches bad: label. Cleanup loop frees every FC channel using SAME stale base and final control-area free also uses stale base. Result: contigfree() double/triple-free of one channel virtual address and leak of every other allocation. For isp_nchan=1 (default): fc[0]_base freed twice (once correctly once at :1673 with wrong/larger size) real control-area base leaked. For isp_nchan=N: last channel base freed N+1 times. Unprivileged user can contribute memory pressure while admin kldload/hotplug supplies attach. Classic kernel-heap double-free primitive.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2474 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | Source trace confirming DF-2474 bug is real but HW-gated | 1.4 KB | β raw |
| fix.diff | suggested-fix | Save control-area base separately and store per-channel base in struct isp_fc | 1.6 KB | view raw |
| env.txt | environment | Guest gate proof: kldstat, pciconf, camcontrol (no target HBA) | 1.1 KB | view raw |
| build.sh | build-script | No buildable PoC (HW-gated) | 384 B | view raw |
| run.sh | run-script | Gate verification commands | 411 B | view raw |
| README.md | readme | Overview of HW-gated finding | 791 B | β raw |
HW-gated SCSI/FC HBA driver finding
This finding targets a SCSI/FC/SATA HBA driver that is not present in this QEMU/KVM guest (only PIIX3 IDE + virtio). The driver cannot attach and the cited code path is unreachable at runtime.
Reproduction status: NOT REPRODUCED (HW-gated)
- The source bug is confirmed real by line-by-line source trace (see VERDICT.md).
- It cannot be triggered because the HBA hardware/driver does not exist on this guest.
- A defense-in-depth
fix.diffhas been authored and validated withgit apply --check.
Evidence
VERDICT.mdβ full source trace and analysisenv.txtβ guest environment (kldstat, pciconf, camcontrol gate proof)fix.diffβ git-apply-able defense-in-depth fixmanifest.jsonβ machine-readable catalog
DF-2474 β Stale base pointer in isp_pci_mbxdma error cleanup
Verdict: NOT REPRODUCED (HW-gated) β source bug CONFIRMED
Hardware gate
No QLogic ISP HBA in guest: kldstat shows only kernel/ehci/xhci; pciconf -l
shows no QLogic device. The isp PCI attach path is never exercised.
Source trace (confirmed real bug)
File: sys/dev/disk/isp/isp_pci.c:1600-1673
isp_pci_mbxdma() uses a single local caddr_t base for both the control-area
allocation (line 1600) and every per-channel FC scratch allocation (line 1629).
The FC loop overwrites base on each iteration. When any later step fails (e.g.,
bus_dmamap_create ENOMEM in the per-command map loop at line 1646-1655), control
reaches bad: at line 1667. The cleanup loop (1668-1672) frees every FC channel
using the same stale base (last channel's address), and the final control-area
free at line 1673 also uses the stale base. Result: double/triple-free of one
channel's virtual address; leak of every other allocation.
Fix
- Added
caddr_t ctrl_baseto save the control-area base before the FC loop - Added
caddr_t rscratchfield tostruct isp_fcto store each channel's base - bad: cleanup uses
fc->rscratchfor per-channel frees andctrl_basefor the control-area free
Spans isp_freebsd.h and isp_pci.c. See fix.diff.
Impact (on HW that has the HBA)
Medium β kernel-heap double-free primitive on error cleanup paths.
Fix verification
not_testablenot_testable: target driver cannot attach (no target HBA). fix.diff validated with git apply --check (EXIT=0); fix is correct by source trace.
git apply --check findings/poc/DF-2474/fix.diff => EXIT=0. No runtime test possible (no target HBA).
Confirmed kernel references
Detail
Exploit chain
none β valid hard blocker (driver code path dead at runtime on this guest: no target HBA). No unprivileged->root path.
Evidence (decisive lines)
kldstat -> kernel/ehci/xhci only (no target driver); pciconf -l -> PIIX3 IDE + virtio only (no target HBA); camcontrol devlist -> only <QEMU QEMU DVD-ROM>. Source confirmed at cited lines.
PoC changes
Created findings/poc/DF-2474/{VERDICT.md,fix.diff,manifest.json,env.txt,build.sh,run.sh,README.md}. No PoC source (HW-gated).
Verified recommended fix
Defense-in-depth fix.diff closes the cited path (see findings/poc/DF-2474/fix.diff; git apply --check OK).
Verdict
NOT REPRODUCED (HW-gated). The bug is REAL in source (traced line-by-line): isp_pci stale base pointer in isp_pci_mbxdma error cleanup (double/triple-free; needs QLogic ISP + mem pressure). Gate confirmed: kldstat (only kernel+ehci+xhci; no isp/mpt/sili/trm/sbp module loaded), pciconf -l (no QLogic ISP/LSI MPT/SiliconImage/Tekram/FireWire HBA β only PIIX3 IDE atapci0 + virtio), camcontrol devlist (only QEMU DVD-ROM). The target driver cannot attach so the cited code path is dead at runtime on this guest.
No comments yet.