DF-0613 — PoC: ng_iface rcvmsg `msg` leak on EBUSY early return
================================================================

Root-only local kernel-memory-exhaustion DoS PoC.

## Files

- `leak_ng_iface.c` — creates an `NG_CONTROL` socket, creates an
  `ng_iface` peer node via `NGM_MKPEER`, queries its interface name
  via `NGM_IFACE_GET_IFNAME`, brings it UP via `SIOCSIFFLAGS`, then
  spams `NGM_IFACE_POINT2POINT` control messages in a tight loop.
  Each iteration leaks the `sizeof(struct ng_mesg) + arglen` request
  buffer because `ng_iface_rcvmsg` does `return (EBUSY)` at line 666,
  bypassing the `kfree(msg)` at line 732.
- `fix.diff` — replaces `return (EBUSY)` with `error = EBUSY; break;`
  so the epilogue at lines 728-733 frees `msg`.
- `build.sh` — compiles the PoC.
- `run.sh` — loads modules, runs the PoC, shows vmstat -m before/after.

## Build & run

```
cc -O2 -Wall -o leak_ng_iface leak_ng_iface.c
# as root, on a host with netgraph + ng_socket + ng_iface loaded:
./leak_ng_iface [iterations] [arglen]
```

## Expected outcome

`vmstat -m | grep netgraph` shows M_NETGRAPH climbing monotonically
(each iteration leaks ~52 bytes with arglen=0). Eventually the system
panics with `kmem_malloc: out of space` or hangs.

With the fix applied, M_NETGRAPH stays flat — the messages are freed
by the epilogue.

## Runtime testing notes

The default GENERIC kernel (#0, INVARIANTS ON) has two separate bugs
that prevent creating ng_iface nodes at runtime (see VERDICT.md and
env.txt). Fix validation was performed on the noinv-installed snapshot
(INVARIANTS OFF) with a test-only constructor fix applied to the
ng_iface module. The DF-0613 fix.diff contains only the EBUSY
return→break change.
