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

hpfs_cpinit error paths leak the hpm_cpdblk allocation (mount-failure memory exhaustion)

Summary

hpm_cpdblk is kmalloc'd at :276 but both error returns (:286 bread failure, :300 cpload failure) return without freeing it, and the caller's cleanup (hpfs_vfsops.c:307 hpfs_bmdeinit) frees only hpm_bitmap/hpm_bmind - each failed mount leaks cpicnt*sizeof(cpdblk) (~136 bytes typical). Distinct allocation from the known DF-0889 (hpmp) mount-failure leak, same family. Unverified (privileged-trigger leak). Fix: kfree before both error returns (included in DF-3144's fix.diff). [VERIFIED pass2: reproduced - 50 failed hpfs mounts grow M_HPFSMNT to 106M in-use zero frees about 2MiB per mount; fix compile-validated]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3145 Β· 11 files
FileTypeDescriptionSize
craft_hpfs_err.py β€” 2.1 KB view raw
run_guest.sh β€” 1.0 KB view raw
run.log β€” 839 B view raw
README.md β€” 542 B ↓ raw
VERDICT.md β€” 1.9 KB ↓ raw
build.sh β€” 141 B view raw
run.sh β€” 181 B view raw
manifest.json β€” 682 B view raw
verdict.json β€” 1.6 KB view raw
fix.diff β€” 526 B view raw
env.txt β€” 272 B view raw

DF-3145 -- verification pack

Finding: hpfs_cpinit error paths leak hpm_cpdblk

Status: reproduced / impact leak / confidence certain

What was run

host: python3 craft_hpfs_err.py out.img

How to reproduce

guest: vnconfig -c -S 8m /dev/vn1 img; loop 50x mount_hpfs -o ro /dev/vn1 /mnt; vmstat -m | grep HPFS

Expected

M_HPFSMNT grows ~2MiB per failed mount with no frees

See VERDICT.md for the full narrative and verdict.json for the persisted machine verdict. Artifacts: craft_hpfs_err.py, run_guest.sh, run.log.

VERDICT.md
↓ download raw

DF-3145 verification

Kernel: DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64

Bottom line

50 failed mounts of the crafted HPFS image (sp_cpinum=0x4000 so hpm_cpdblk = 16384 * sizeof(struct cpdblk), sp_cpi far past EOF so the first bread fails and hpfs_cpinit returns at hpfs_subr.c:286 without freeing) grew the M_HPFSMNT malloc zone from empty to 106M in-use with 200 allocations and zero frees - about 2MiB of cpdblk leaked per failed mount (plus the separately-known hpmp mount-failure leak, DF-0889 family). Caller cleanup only frees hpm_bitmap/hpm_bmind via hpfs_bmdeinit, never cpdblk. Privileged mount trigger; resource exhaustion only. Fix frees cpdblk on both error paths; compile-validated.

Kernel references

Exploit chain

(none: availability/correctness finding; no privilege chain)

Fix

kfree hpm_cpdblk on both error returns

See fix.diff in this directory (git-apply-able against the read-only sys/ tree; applied only inside the disposable verification guest).

Reproduction

build: host: python3 craft_hpfs_err.py out.img

run: guest: vnconfig -c -S 8m /dev/vn1 img; loop 50x mount_hpfs -o ro /dev/vn1 /mnt; vmstat -m | grep HPFS

expected: M_HPFSMNT grows ~2MiB per failed mount with no frees

Notes on the PoC (what changed vs the finding sketch)

image adapted from the DF-3144 rig with sp_cpi = 0x40000 (bread fails immediately) instead of the livelock shape

Fix status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

Fix verification

not_testable
↓ fix.diffper-fix-DF-3145

Confirmed kernel references

Detail

Evidence (decisive lines)

run.log: vmstat -m HPFS_mount line 0 -> 100 in-use / 106M after 50 failed mounts, mount attempts=50 failed=50

PoC changes

image adapted from the DF-3144 rig with sp_cpi = 0x40000 (bread fails immediately) instead of the livelock shape

Verified recommended fix

kfree hpm_cpdblk on both error returns

Verdict

50 failed mounts of the crafted HPFS image (sp_cpinum=0x4000 so hpm_cpdblk = 16384 * sizeof(struct cpdblk), sp_cpi far past EOF so the first bread fails and hpfs_cpinit returns at hpfs_subr.c:286 without freeing) grew the M_HPFSMNT malloc zone from empty to 106M in-use with 200 allocations and zero frees - about 2MiB of cpdblk leaked per failed mount (plus the separately-known hpmp mount-failure leak, DF-0889 family). Caller cleanup only frees hpm_bitmap/hpm_bmind via hpfs_bmdeinit, never cpdblk. Privileged mount trigger; resource exhaustion only. Fix frees cpdblk on both error paths; compile-validated.