# DF-3083 VERDICT

## Bottom line

**REPRODUCED.** A single corrupted byte in a directory entry (`rec_len`
16 → 17, violating `rec_len % 4 == 0`) turns any **read-write mounted**
ext2 filesystem into an immediate kernel panic: one unprivileged path
lookup that walks past the entry (e.g. `stat /mnt/e2/d/file4`) hits
`ext2_check_direntry()` failure → `ext2_search_dirblock()` calls
`ext2_dirbad()` (sys/vfs/ext2fs/ext2_lookup.c:701) → `panic()`
(ext2_lookup.c:777-780) because the mount is not MNT_RDONLY.
The identical lookup on a read-only mount survives (the non-fatal
SDT branch), and the walker already contains the recovery
(skip to next block, ext2_lookup.c:702-706).

## Baseline run (stock #0)

RO control survived (mount/ls/umount all completed); RW mount:

```
stat /mnt/e2/d/file4
panic: ext2_dirbad: /mnt/e2: bad dir ino 12 at offset 56: mangled entry
ext2_dirbad() at ext2_dirbad+0x32
ext2_search_dirblock() at ext2_search_dirblock+0x194
ext2_lookup() at ext2_lookup+0x1fe
vop_compat_nresolve() at vop_compat_nresolve+0x82
```
(panic.txt; offset 56 = the patched entry in dir inode 12.)

## Trigger caveat (poc_changes)

The first attempt used `ls -l` as the trigger; the mangled entry also
breaks `readdir`, which EIOs before emitting names, so no lstat ever walked
into the corrupt entry. A direct `stat` of a name positioned after the
corrupt entry is the deterministic trigger (run.sh updated accordingly).

## Fix validation (kernel #1, single-fix build shared with DF-3082)

Same image, RW mount, same lookup:
```
stat file4 rc=1 (ENOENT expected, NO panic)
stat file1 ok
ext2_dirbad: : bad dir ino 12 at offset 56: mangled entry   <- console printf
FIX-OK: RW mount survived mangled-entry lookup
```
The console line proves the walker reached the same code point and now
logs instead of panicking; entries before the corrupt byte remain
resolvable.

## Impact

Local kernel panic (DoS) from a crafted image on a writable mount — by an
admin mounting untrusted media, or fully unprivileged with
`vfs.usermount=1` (0 on this guest, but a supported configuration). Also
the automatic follow-on of DF-3082 on *valid* images (freed htree leaf
blocks read back zero-filled → "mangled entry" → panic), which is how
DF-3082's demonstration ended.
