# DF-0788 — Heap info leak via resident attribute data offset in `ntfs_attrtontvattr`

**Severity:** Medium | **Status:** reproduced | **Impact:** heap OOB read / info leak

## Summary

`ntfs_attrtontvattr()` (`sys/vfs/ntfs/ntfs_subr.c:557-564`) trusts the on-disk
`u_int16_t a_r.a_dataoff` field without validation.  A crafted NTFS image can
set this offset past the MFT record buffer boundary, causing `memcpy` to read
adjacent kernel heap into an attribute buffer later exposed to userspace.

## Reproduce

### Prerequisites
- DragonFlyBSD master DEV guest ( GENERIC kernel, INVARIANTS ON)
- Python 3 (host-side, for image generation)
- The guest needs `cc` (installed by default)

### Build & run the harness (deterministic proof, no root needed)
```sh
./build.sh        # builds harness.c + generates ntfs_0788.img (needs python3)
./run.sh          # runs the harness: clean / oob_dataoff / oob_dataoff apply_fix
```

If python3 is not on the host/guest, generate the image separately:
```sh
python3 gen_ntfs_0788.py ntfs_0788.img   # on host
scp ntfs_0788.img dfbsd-maxx:poc/DF-0788/
```

### Expected output (harness)
```
mode=clean        -> rc=0  memcpy within bounds (clean)
mode=oob_dataoff  -> rc=2  SIGSEGV -> OOB READ past record (LEAK CONFIRMED)
mode=oob_dataoff apply_fix -> rc=1  FIX REJECTED malformed attribute (EINVAL)
```

### Live kernel trigger (requires root)
```sh
vnconfig -c vn0 /root/ntfs_0788.img
mount_ntfs -o ro /dev/vn0 /mnt/ntfs     # UNPATCHED: succeeds (OOB read happens)
                                        # PATCHED:   "Invalid argument" (EINVAL)
```

## Files

| File | Description |
|------|-------------|
| `harness.c` | Deterministic userspace harness mirroring `ntfs_attrtontvattr` resident memcpy with guard page |
| `gen_ntfs_0788.py` | Crafted NTFS image generator (corrupts ino 5 `$INDEX_ROOT` `a_dataoff`) |
| `ntfs_0788.img` | Pre-generated crafted image (256 KB) |
| `build.sh` / `run.sh` | Reproducible build/run scripts |
| `fix.diff` | git-apply-able fix: validate offsets against `a_hdr.reclen` |
| `VERDICT.md` | Full analysis: mechanism, reachability, impact, fix validation |
| `build.log` | Harness build output |
| `run.log` | Harness run output (decisive) |
| `panic.txt` | Live-trigger panic signature (DF-0786 sibling, not DF-0788) |
| `baseline_mount.log` | Unpatched #0 kernel: mount succeeds (OOB read) |
| `fix_run.log` | Patched #1 kernel: mount fails EINVAL |
| `fix_build.log` | Single-fix kernel + module build log |
| `env.txt` | Guest environment (uname, cc, sysctls) |
