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

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3165 Β· 7 files
FileTypeDescriptionSize
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

fixed
baseline reproduced→ patch + rebuild →patched clean

fix.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']
↓ fix.diffDragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Mon Sep 7 11:10:39 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64

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.