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)
PoC verification
Evidence pack
findings/poc/DF-3249 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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_testablefix.diff applied in the F40FIX verification kernel build (RC=0, zero -Werror errors); no runtime A/B for this item (line-certain hardening)
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.
No comments yet.