# DF-0790 — ATTRLIST parsing DoS in `ntfs_ntvattrget`

**Verdict:** REPRODUCED (live kernel hang + deterministic harness) → FIX VALIDATED
**Impact:** `dos` (kernel hang / local DoS via crafted NTFS image; no escalation)
**Confidence:** certain

## What this is

`ntfs_ntvattrget` (`sys/vfs/ntfs/ntfs_subr.c:196-236`) walks the on-disk `$ATTRIBUTE_LIST`
to find an attribute referenced from another MFT record. The walk advances by `aalp->reclen`
without checking `reclen == 0` (→ infinite loop / kernel hang) or `reclen > len`
(→ `size_t` underflow → NULL deref panic). A crafted NTFS image triggers it at mount time.

## How to reproduce

### 1. Userspace harness (deterministic, unprivileged)
```sh
ssh -F dfbsd-qemu/config dfbsd-maxx 'mkdir -p poc/DF-0790'
scp -F dfbsd-qemu/config -q {harness.c,build.sh,run.sh} dfbsd-maxx:poc/DF-0790/
ssh -F dfbsd-qemu/config dfbsd-maxx 'cd poc/DF-0790 && sh build.sh && sh run.sh'
```
Expected: `loop` → rc=1 (iteration cap = infinite loop in kernel); `null` → rc=2 (SIGSEGV = NULL deref).

### 2. Live kernel trigger (root — EXPECTS HANG, guest dies)
```sh
python3 gen_ntfs_0790.py mount_loop ntfs_0790_mount_loop.img
scp -F dfbsd-qemu/config -q ntfs_0790_mount_loop.img dfbsd:/root/
./dfbsd-qemu/vm.sh run_root 'vnconfig -c vn0 /root/ntfs_0790_mount_loop.img && mount_ntfs -o ro /dev/vn0 /mnt/ntfs'
# ^mount(2) NEVER RETURNS — guest wedged (infinite loop in ntfs_ntvattrget)
./dfbsd-qemu/vm.sh reset with-src
```

### 3. Fix validation (rebuild ntfs.ko module — no kernel reboot needed)
```sh
scp -F dfbsd-qemu/config -q fix.diff dfbsd:/root/
./dfbsd-qemu/vm.sh run_root 'cd /usr/src && patch -p1 < /root/fix.diff && cd sys/vfs/ntfs && KERNCONF=X86_64_GENERIC make && cp ntfs.ko /boot/kernel/ntfs.ko'
# re-run step 2; mount now fails cleanly: "Invalid argument" (EINVAL), guest stays UP
# dmesg: ntfs_ntvattrget: malformed attrlist entry (reclen 0, len 26)
```

## Files
- `harness.c` — deterministic userspace replication of the ATTRLIST walk (guard-page backed).
- `gen_ntfs_0790.py` — crafted NTFS image generator (ino-5 and mount-time ino-6 variants).
- `fix.diff` — the validated fix (rejects reclen==0 / reclen>len with EINVAL).
- `VERDICT.md` — full narrative with path:line citations.
- `hang_evidence.txt` / `fix_run.log` — live before/after evidence.
