# DF-3435 — ipfw3 `check_keep_state()` writes through an unchecked `M_NULLOK` kmalloc — NULL-page write at the malloc-type limit

`sys/net/ipfw3_basic/ip_fw3_state.c:319-321`:

```c
s = kmalloc(LEN_FW3_STATE, M_IPFW3_STATE, M_INTWAIT | M_NULLOK | M_ZERO);
s->src_addr = k->src_addr;      /* s == NULL -> write at vaddr 0x18 */
```

`M_NULLOK` explicitly permits a NULL return when the malloc-type limit is
reached (`sys/kern/kern_slaballoc.c:694-705`: `if (flags & M_NULLOK)
return(NULL);`). The default `M_IPFW3_STATE` limit is
`kmem_lim_size()/10` (≈390 MB on the 4.25 GB guest). The shipped per-tree
caps (`state_max_*` = 4096) keep the path cold, but they are plain
`CTLFLAG_RW` sysctls — any deployment that raises them (or a machine where
the type limit is otherwise exhausted) converts unprivileged
state-creating traffic into a kernel write at `NULL+offset`
(`Fatal trap 12: page fault on write`, vaddr 0x18).

## Reproduce attempted on the guest (see VERDICT.md)

- `state_null.c`   — raw-socket unique-5-tuple UDP flood (slow path,
                     ~1k pps synchronous)
- `state_null_tap.c` — tap-frame injector, ~250k pps write rate;
                     ~35M packets got the tree to ~190K live states
                     (~12 MB) before the session's guest budget ended;
                     the netisr drain (~2-7k pps with a populated tree,
                     aggravated by the O(n)-per-packet limit counting at
                     ip_fw3_state.c:302) is the bottleneck, not the
                     defect.

Expected terminal output had the flood completed to 6.1M live states:
`Fatal trap 12: page fault while in kernel mode ... fault virtual address
= 0x18 ... supervisor write data` inside `check_keep_state`.

## Fix (fix.diff)

Keep `M_NULLOK`, check the result: `if (s == NULL) goto done;`
(do **not** drop `M_NULLOK` — that converts the limit-hit into
`panic("malloc limit exceeded")`).
