# DF-3483 VERDICT — ng_generic_msg arglen-mismatch leaks the control message

**Status: reproduced** (kernel memory leak, permanent, unbounded; root-gated)

## Root cause
`ng_generic_msg()` implements the four argument-carrying generic commands.
Each first validates `msg->header.arglen` and on mismatch does
`TRAP_ERROR; return (EINVAL);` — WITHOUT freeing `msg`:

- NGM_MKPEER   ng_base.c:1263-1266
- NGM_CONNECT  ng_base.c:1279-1282
- NGM_NAME     ng_base.c:1296-1299
- NGM_RMHOOK   ng_base.c:1309-1312

The function's contract (and every other exit path) frees the message:
the cookie-mismatch path kfrees (1252-1253), the default case falls through
to `kfree(msg)` (1669), and successful handlers pass ownership onward.
Neither caller frees on error: `ng_send_msg()` (1207-1239) only kfrees the
retaddr, and `ngintr()` (2062) assumes the handler freed it.  The leaked
allocation is the buffer `ngc_send` kmalloc'd for the user's sendto payload
(user-chosen length; 149-249 bytes in the PoC) — permanent, unbounded,
reclaimable only by reboot.  This is the v1 sibling of netgraph7's DF-3474:
v1 has no NG_FREE_ITEM/item abstraction (its ng_queue_entry objects are
genuinely freed), but generic-handler error paths leak the control message
itself.

## Reachability / threat
Control sockets are `SYSCAP_RESTRICTEDROOT`-gated (ng_socket.c:172-176), so
the direct trigger is root (ngctl-equivalent traffic, long-running root
daemons driving netgraph).  A root loop leaks kernel heap without bound:
200k bad sends in the PoC leaked ~30 MB.  Impact: local kernel-memory
exhaustion DoS (kldload/fork/socket allocations degrade); no info leak, no
corruption.  Non-generic node types' rcvmsg handlers with the same
early-return pattern are separately auditable (out of this file's scope).

## Evidence (baseline, stock modules)
run.log / run.2.log — 50k-iteration phases, free-page deltas:
  good  104 /  -1  pages   (addressing failure path kfrees correctly)
  bad  1935 / 1861 pages   (MKPEER arglen-1; predicted 1953 = 50000 x 160B zone)
  bad2 1122 / 1154 pages   (NAME  arglen-1; predicted 1172 = 50000 x 96B zone)
The leaked-byte arithmetic matches the allocation zone size exactly for
both independent sites — the leak is the ng_mesg buffer itself.

## Fix validation
fix.diff adds `kfree(msg, M_NETGRAPH);` before each of the four early
returns.  Patched netgraph.ko built in-guest (-Werror), loaded on a fresh
boot, same PoC (fix_run.log):
  bad     11 / 1 pages  (noise)
  bad2     0 / 0 pages
Leak eliminated; good path unchanged.  fix_status: fixed.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
