# DF-3511 — ng_socket.c `ngc_send()` MKPEER module-autoload path: `goto done`
## skips every free — msg + path + mbuf leaked per sendto (and module autoload
## via AF_NETGRAPH is always ENXIO)

## Where

`sys/netgraph7/socket/ng_socket.c`, `ngc_send()`:

- `msg = kmalloc(len + 1, M_NETGRAPH_MSG, M_WAITOK)` at **ng_socket.c:261**
- `path = kmalloc(len + 1, M_NETGRAPH_PATH, M_WAITOK)` at **ng_socket.c:246**
- MKPEER autoload interception at **ng_socket.c:276-307**:
  when `ng_findtype(mkp->type) == NULL` and `!linker_api_available()`
  (**ng_socket.c:285-288**) it does `error = ENXIO; goto done;`
- `done:` (**ng_socket.c:351**) sits *after* the `release:` block
  (**ng_socket.c:344-350**) that frees `path`, `control`, and `m`.
  `msg` has no other free on this path (it is only kfree'd at :265/:295/:301,
  all *other* exits of the loader block).

On DragonFly, `pru_send` handlers execute on a socket protocol thread where
`curproc == NULL`, so `linker_api_available()`
(**ng_socket.c:1175-1188**: `curproc == NULL || namei_oc == NULL`) returns 0
**on every send** — the `goto done` path is not a boot-time corner case, it is
the *only* outcome of "MKPEER with a type that is not already loaded":

* every such sendto(2) permanently leaks `kmalloc(len+1, M_NETGRAPH_MSG)`
  (user-chosen len), the path allocation, and the sendto mbuf;
* module autoload through AF_NETGRAPH sockets never works (always ENXIO).

## Reachability / privilege

Control sockets are privilege-gated
(`ngc_attach`, **ng_socket.c:182-184**: `caps_priv_check(SYSCAP_RESTRICTEDROOT)`)
→ the trigger requires root. Ceiling: unbounded kernel-memory + mbuf leak
(resource-exhaustion DoS) by an already-privileged user; no memory corruption,
no unprivileged route.

## Reproduce (in guest, root)

```
sh /root/df3511/build.sh          # builds netgraph7 netgraph.ko + ng_socket.ko + trigger
sh /root/df3511/run.sh            # kldloads modules, runs A (control) then B (leak)
```

Expected (unfixed kernel — see run.log):

```
[type=socket  ] sendto ok=0 fail=50000 ... errno 22 (EINVAL): 50000   <- control
[type=df3511x ] sendto ok=0 fail=50000 ... errno 6  (ENXIO):  50000   <- leak live
free-before: 839636 -> afterA: 839220 (flat) -> afterB: 830848 (-8372 pages)
mbufs in use: 14 -> 12 (A) -> 50012 (B)     # exactly +1 leaked mbuf per send
```

With `fix.diff` applied to the guest's /usr/src copy and the module rebuilt
(fix_run.log): identical ENXIO/EINVAL behavior but memory flat and mbufs 7->7.

## Fix

`fix.diff` (2 hunks): free `msg` and `goto release` (the pattern already used
by the sibling error exits at ng_socket.c:294-297), and drop the now-unused
`done:` label.
