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

ext2_clusteracct computes a negative shift count (1 << (start % NBBY) with start=-1) when freeing/accounting cg-relative bit 0 β€” C99 undefined behavior, no observable effect on x86

Summary

ext2_subr.c:175 sets start = bno - 1 for the backward cluster scan; when the caller passes cg-relative bno==0 (craftable by clearing bit 0 of a group bitmap on an ext2 image, which passes the INVARIANTS isset-dup-alloc check), start becomes -1 and :180 evaluates bit = 1 << (start % NBBY) == 1 << -1, plus loc = -1/8 - both undefined per C99. On x86 the shift count masks to 31 and the loop body (for i=-1; i>end; i--, end clamped to -1) never executes, so back=0 and accounting stays correct; no memory-safety effect. Pure hardening; the identical FFS lineage code shares the wart. Fix: guard the backward scan against bno==0. [VERIFIED pass2: 1 shift minus-1 UB at bno 0 confirmed no observable effect on x86; backward-scan guard compiled]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3249 Β· 4 files
FileTypeDescriptionSize
README.md β€” 242 B ↓ raw
fix.diff β€” 795 B view raw
manifest.json β€” 356 B view raw
verdict.json β€” 1.5 KB view raw

DF-3249 evidence pack

What

ext2_clusteracct computes 1 << -1 (UB) when freeing cg-relative bit 0

Verdict

status=not_reproduced impact=none confidence=certain

See VERDICT.md for the full narrative and fix.diff for the verified fix.

Fix verification

not_testable

fix.diff applied in the F40FIX verification kernel build (RC=0, zero -Werror errors); no runtime A/B for this item (line-certain hardening)

↓ fix.diffper-fix-DF-3249

Confirmed kernel references

Detail

Evidence (decisive lines)

VERDICT.md with path:line citations; run.log where a live demo exists; fix.diff

PoC changes

n/a - no observable effect on x86

Verified recommended fix

skip the backward cluster scan when bno == 0 (start < 0)

Verdict

Line-accurate confirmation; no runtime manifestation exists on x86 (shift count masks to 31; loc = -1/8 = 0; the loop body never executes because end clamps to -1 and i starts at -1, so back=0 and accounting stays correct). ext2_subr.c:175 sets start = bno - 1 for the backward scan; with cg-relative bno==0 (craftable by clearing bit 0 of a group bitmap) :180 evaluates bit = 1 << (start % NBBY) == 1 << -1 and loc = start/NBBY - undefined per C99. Pure hardening; the FFS lineage code shares the wart. Fix guards the backward scan with start >= 0; compiled in the F40FIX build.