doff_t (int32) truncation of crafted directory i_size >= 2^31 yields negative dp->i_offset -> ext2_write KASSERT panic on INVARIANTS kernels (EINVAL elsewhere)
Summary
endsearch = roundup2(dp->i_size, DIRBLKSIZ) and dp->i_offset = roundup2(dp->i_size, DIRBLKSIZ) truncate a crafted uint64 directory i_size (e.g. 0x80000000) into negative int32 doff_t: the search loop silently skipped (:424/:428), CREATE falls into slotstatus==NONE with dp->i_offset = INT32_MIN (:496), and ext2_direnter -> ext2_add_first_entry passes the negative offset to VOP_WRITE hitting ext2_write's KASSERT(uio_offset >= 0) - panic on INVARIANTS/debug builds (the audit guest's stock config); production EINVAL via maxfilesize. Traced certainty, not guest-run (Low). Fix: clamp directory offsets / reject oversized directory inodes at ext2_iget. [VERIFIED pass2: reproduced exactly - dir i_size 0x80000000 via debugfs craft, unpriv touch panics stock INVARIANTS ext2_write uio_offset lt 0; EINVAL fix A/B clean]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3084 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 317 B | β raw | |
| VERDICT.md | β | 1.7 KB | β raw | |
| env.txt | β | 248 B | view raw | |
| fix.diff | β | 531 B | view raw | |
| manifest.json | β | 765 B | view raw | |
| panic.txt | β | 13.6 KB | view raw | |
| run.log | β | 339 B | view raw | |
| verdict.json | β | 2.0 KB | view raw |
DF-3084 - doff_t (int32) truncation of crafted directory i_size >= 2^31 -> negative i_offset -> ext2_write KASSERT
Severity Low | verdict: reproduced | impact: panic
Reproduce
No runnable PoC on this rig (see VERDICT.md for why).
See VERDICT.md for the full narrative and run.log for the decisive output.
DF-3084 verification
Kernel: DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64
Exact predicted reproduction: ext2 image crafted on the host (mke2fs + debugfs sif
Kernel references
- sys/vfs/ext2fs/ext2_lookup.c:424
- sys/vfs/ext2fs/ext2_lookup.c:496
- sys/vfs/ext2fs/ext2_vnops.c:1980
- sys/vfs/ext2fs/inode.h:53
Fix
See fix.diff.
Fix validation (A/B on rebuilt kernel #0 Sun Oct 25 06:10:12 UTC 2026)
fix_status: fixed - A/B validated: same crafted image + unpriv touch on the fix kernel returns clean EINVAL (touch: /mnt/e84/d/newfile: Invalid argument), no panic (baseline panic.txt vs fixed-run log)
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testableConfirmed kernel references
Detail
Exploit chain
crafted dir i_size 0x80000000 -> ext2_lookup_ino search skipped (endsearch negative) -> CREATE notfound path dp->i_offset=INT32_MIN -> ext2_add_first_entry auio.uio_offset negative -> VOP_WRITE -> KASSERT(uio_offset >= 0) panic
Evidence (decisive lines)
VERDICT.md + run.log + panic.txt + fix.diff (A/B: fixed kernel #0 Sun Oct 25 06:10:12 UTC 2026)
PoC changes
none
Verified recommended fix
fix.diff rejects directory sizes that would truncate negative through doff_t at the notfound/create path; A/B validated on the fixed kernel.
Verdict
Exact predicted reproduction: ext2 image crafted on the host (mke2fs + debugfs sif
No comments yet.