# DF-0705 — Three independent panics in ip_fw3_sync.c (edge_start / show_conf)

## Verdict: NOT REPRODUCED (LATENT — same dead-code reason as DF-0704)

## Cited panics (all in sys/net/ipfw3_basic/ip_fw3_sync.c)

1. **`edge_start` line 248** — `sobind(fw3_sync_ctx.edge_sock, ...)` with
   no NULL check. If `edge_conf` has not been called first,
   `fw3_sync_ctx.edge_sock` is NULL → sobind derefs NULL.
2. **`edge_start` line 262-264** — `panic("...:error %d",error)` on
   `kthread_create` failure instead of returning the error.
3. **`show_conf` line 105-116** — `int size = 3*sizeof(int) + count*LEN_SYNC_EDGE`
   where `count` is signed; a negative `count` makes `size` small, bypassing
   `if (sopt_valsize < size)`, then `bcopy(..., count*LEN_SYNC_EDGE)` with
   `count` cast to `size_t` becomes a ~4 GiB write → page fault.

## Why none of them reproduce

Same root cause as DF-0704: the dispatch pointer `ip_fw3_ctl_sync_ptr`
(sys/net/ipfw3/ip_fw3.c:133) is initialised to NULL and **never assigned
anywhere in the source tree**. The IP_FW_SYNC_* sockopt cases fall
through the `if (ip_fw3_ctl_sync_ptr != NULL)` guard at line 1125 with
no effect.

The probe `ipfw3_sync_probe.c` issues the three "panic-trigger" opcodes
(IP_FW_SYNC_EDGE_START = 85, IP_FW_SYNC_CENTRE_CONF = 89 with count=-1,
IP_FW_SYNC_SHOW_CONF = 82) via `IP_FW_X` setsockopt on a raw IP socket.
After loading `ipfw3.ko` and `ipfw3_basic.ko`, **all three return rc=0
with no effect** — the dispatch pointer is still NULL:

```
[fire opcode=85 plen=0]  setsockopt rc=0 errno=0   # edge_start, NULL edge_sock
[fire opcode=89 plen=4]  setsockopt rc=0 errno=0   # centre_conf, count=-1
[fire opcode=82 plen=64] setsockopt rc=0 errno=0   # show_conf, negative count
[+] All three returned without panic.
```

Guest stays up. The cited panics are unreachable on a default kernel.

## Privilege note

Even when the dispatch pointer is hooked up (a one-line source change),
the IP_FW_X path requires a raw IP socket, which requires
`caps_priv_check(SYSCAP_NONET_RAW)` (sys/netinet/raw_ip.c:473). So the
cited panics are **root-only** triggers regardless. Root→kernel panic is
a hardening gap, not an unprivileged escalation.

## Fix

`fix.diff` addresses all three:

- `edge_start` — NULL check on `fw3_sync_ctx.edge_sock` (return EINVAL);
  replace `panic()` on `kthread_create` failure with `kprintf` + return
  error.
- `show_conf` — reject negative `fw3_sync_ctx.count` before computing
  `size`; cast `size` to `size_t` for the sopt_valsize compare.
- `centre_conf` — validate `ioc_centre->count` is non-negative and
  bounded (≤ MAX_EDGES) before the kmalloc/bcopy.

Combined with the DF-0704 fix, this hardens the entire ipfw3_sync code
path against the listed panics for whenever someone wires it up.

## Files

- `ipfw3_sync_probe.c` — same probe as DF-0704 (also confirms DF-0705 dead)
- `run.log` — probe output
- `fix.diff` — NULL check + kthread error + count bounds
- `VERDICT.md` — this analysis
