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

hpfs_cpinit mount-time livelock: 'while (cpicnt > 0)' never terminates when every cpisec carries s_cpicnt == 0 and s_next chains (self-loop)

Summary

cpicnt (from sp_cpinum) is only decremented inside 'for (i=0; i<cpisp->s_cpicnt; i++, cpicnt--)' (:292); s_cpicnt and s_next are raw on-disk fields and CPI_MAGIC is never checked. With sp_cpinum>=1 and a cpisec with s_cpicnt==0/s_next=self, mount(2) breads the same sector forever inside hpfs_cpinit. Mounting a crafted/corrupted HPFS image (root or vfs.usermount=1): mount never completes and cannot be aborted (unkillable), guest degrades. VERIFIED: no MOUNT_RC ever, inner timeout(15) could not kill mount(2), outer ssh killed at 30s, follow-up ssh banner-timeout; guest force-killed. Fix: cap the cpisec-chain iteration count (e.g. 16) -> EINVAL (diff in pack; also fixes DF-3145).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3144 Β· 5 files
FileTypeDescriptionSize
craft_img.py β€” 2.2 KB view raw
run.log β€” 597 B view raw
env.txt β€” 150 B view raw
fix.diff β€” 662 B view raw
build.log β€” 158 B view raw

Fix verification

not_testable
baseline reproduced→ patch + rebuild →patched clean

not_testable (no patched-kernel run for this finding)

↓ fix.diffper-fix-DF-3144

Confirmed kernel references

Detail

Evidence (decisive lines)

['run.log: SSH_RC=124 with no MOUNT_RC ever printed; banner-timeout probe; guest force-killed']

PoC changes

none (first attempt worked)

Verified recommended fix

Bound the cpisec-chain iteration count (fix.diff); also kfree hpm_cpdblk on the error returns (DF-3145)

Verdict

Reproduced on the stock kernel: mounting (as root, via direct mount(2)) an image with sp_cpinum=1 and a cpisec carrying s_cpicnt=0 / s_next=self hangs mount(2) forever inside hpfs_cpinit's bread loop. The inner timeout(15) could not terminate the mount; the outer ssh was killed at 30s; a follow-up ssh hit 'Connection timed out during banner exchange' (same sshd-starvation signature as DF-3143). Mount never completes and cannot be aborted; reboot required. cpisec magic (CPI_MAGIC) is never checked either, but the missing loop bound is the bug.