hpfs_bmlookup off-by-one ('lsn > su_btotal' admits lsn == su_btotal): step-1 probe reads exactly one word past the hpm_bitmap kmalloc on exact-band volumes
Summary
The volume check at :340 rejects lsn > su_btotal but admits lsn == su_btotal; valid LSNs are 0..su_btotal-1. With su_btotal an exact band multiple (attacker-chosen), i = lsn>>5 equals hpm_dbnum*BMSIZE/4 words - exactly one word past the bitmap allocation - and the probe reads 4 bytes OOB (up to 32 more reads of the same word in the k-loop). Reached from hpfs_addextent's append branch (alsubr.c:435, lsn = al_lsn+al_len, both on-disk) via a single unpriv pwrite that extends a file. VERIFIED via diagnostic kernel: 'OOB PROBE: i=512 alloc_words=512 lsn=0x4000 su_btotal=0x4000 dbnum=1' (the triggering pwrite completed normally; no disclosure path - hardening-grade). Fix validated (>=): probe never fires.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3142 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| craft_img.py | β | 4.6 KB | view raw | |
| poc.c | β | 1.3 KB | view raw | |
| probe_line.txt | β | 77 B | view raw | |
| run.log | β | 1.5 KB | view raw | |
| fix.diff | β | 301 B | view raw | |
| env.txt | β | 150 B | view raw | |
| build.log | β | 288 B | view raw |
Fix verification
fixedBaseline: probe line proves word 512 read past a 512-word allocation. Patched: no probe line; the same pwrite-extend returns ENOSPC (OUT OF VOLUME) instead of consulting out-of-range memory.
run.log (baseline + fix sections)
Confirmed kernel references
Detail
Evidence (decisive lines)
['probe_line.txt / run.log: DF3142 OOB PROBE: i=512 alloc_words=512 lsn=0x4000 su_btotal=0x4000 dbnum=1', 'run.log fix section: pwrite extend = -1 (ENOSPC), zero DF3142 lines post-fix']
PoC changes
Initial image put the fnode at the last sector (0x3FFF, LSN%8==7) to use the h_no+1 call site - that tripped DF-3141's vget read-fault first (inherent: last sector of an exact-band volume is always LSN%8==7). Reworked to a page-safe fnode (0x48) whose leaf {al_off:0, al_len:2, al_lsn:0x3FFE} reaches the same OOB via the al_lsn+al_len call site (alsubr.c:435).
Verified recommended fix
hpfs_subr.c:340: change lsn > hpmp->hpm_su.su_btotal to lsn >= hpmp->hpm_su.su_btotal
Verdict
Reproduced via a one-line kernel probe in bmlookup step 1 (diag build): extending a file whose leaf satisfies al_lsn+al_len == su_btotal == 0x4000 drives i=512 against a 512-word bitmap allocation - the probe line printed i=512 alloc_words=512 lsn=0x4000. The OOB read's value only feeds a bit test/run count and downstream bmmarkbusy rejects out-of-volume results (pwrite completed normally); no disclosure or corruption path identified, so impact is 'none' beyond the OOB read itself. Fix (lsn > su_btotal -> lsn >= su_btotal) validated on the rebuilt kernel: pwrite returns ENOSPC (OUT OF VOLUME) and no probe line appears.
No comments yet.