Unchecked on-disk lengths rootdir_icb.len and pms->st_size flow into bread/getblk: deterministic 'size > MAXBSIZE' panic at mount of a crafted image
Summary
udf_mountfs:373 copies the on-disk u32 rootdir_icb.len from the File Set Descriptor into 'size' and passes it unchecked through udf_readlblks' int parameter into bread -> getblk, which panics (vfs_bio.c:2738) once the rounded size exceeds MAXBSIZE (65536); values >= 0x80000000 additionally wrap the int size negative into buffer-cache code that only guards size > MAXBSIZE. Identical pattern for pms->st_size in udf_find_partmaps (:662 kmalloc up to 4GB-1, :673 udf_readlblks) from a crafted type-2 sparable partition map. Crafted UDF image (untrusted media / usermount) panics the kernel at mount time - deterministic local DoS, same bucket as DF-0883. VERIFIED: FSD rootdir_icb.len patched 2048->0x100000 on the DF-3102 base image; mount -> 'panic: getblk: size(1048576) > MAXBSIZE(65536)', stack getblk<-breadnx<-udf_mount<-vfs_mount<-sys_mount. Fix validated (reject len==0 || >MAXBSIZE for root_icb.len and st_size): console 'Invalid root file entry length', EINVAL cleanly, guest up.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3165 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| craft_img.py | β | 1.6 KB | view raw | |
| run.sh | β | 157 B | view raw | |
| df3165.udf | β | 1.0 MB | β download | |
| panic.txt | β | 2.2 KB | view raw | |
| panic_core.txt | β | 433 B | view raw | |
| fix_run.log | β | 450 B | view raw | |
| fix.diff | β | 1.1 KB | view raw |
Fix verification
fixedfix.diff applied in guest /usr/src (together with DF-3164's fix, single rebuild). Identical PoC on the rebuilt kernel: 'Invalid root file entry length 1048576' on console, mount fails EINVAL, guest stays up - panic eliminated.
['findings/poc/DF-3165/fix_run.log', 'findings/poc/DF-3165/fix.diff']
Confirmed kernel references
Detail
Evidence (decisive lines)
["findings/poc/DF-3165/panic.txt: serial console with 'panic: getblk: size(1048576) > MAXBSIZE(65536)' and stack getblk <- breadnx <- udf_mount.part.2 <- vfs_mount <- sys_mount", 'findings/poc/DF-3165/panic_core.txt: decisive panic lines', "findings/poc/DF-3165/fix_run.log: 'mount_udf: /dev/vn0: Invalid argument' + dmesg 'Invalid root file entry length 1048576', guest up", 'findings/poc/DF-3165/craft_img.py: 4-byte patch of FSD rootdir_icb.len on the proven DF-3102 base image']
PoC changes
First generator (hand-rolled minimal ECMA-167 structures) failed silently at the anchor checktag; replaced by patching rootdir_icb.len on the known-good DF-3102 base image (field lies outside the 16-byte tag checksum), which reproduced immediately.
Verified recommended fix
Validate on-disk lengths before use: reject root_icb.len and pms->st_size of 0 or > MAXBSIZE (udf_vfsops.c:373 / udf_find_partmaps).
Verdict
rootdir_icb.len is a u32 copied verbatim from the on-disk File Set Descriptor into udf_readlblks (int size) -> bread -> getblk, which panics ('size > MAXBSIZE', vfs_bio.c:2738) for any crafted value above 64 KB; pms->st_size in udf_find_partmaps reaches the same sink. Reproduced deterministically on the stock guest: FSD rootdir_icb.len=0x100000 panicked the kernel at mount with the exact predicted stack (getblk <- breadnx <- udf_mount.part.2 <- sys_mount). Fixed by validating both lengths (0 < len <= MAXBSIZE) before use; on the rebuilt kernel the same image yields 'Invalid root file entry length 1048576' + clean EINVAL with no panic.
No comments yet.