# DF-0607 — Verdict: NOT REPRODUCED (false positive — wrong source tree cited)

## Summary

The finding cites `sys/netgraph7/iface/ng_iface.c:428-431, 481` as containing a
bug where `ng_iface_output` reads uninitialized `dst->sa_data` for BPF writes
on a DLT_NULL interface. While this bug **does exist in the cited source file**,
that file is **dead code** — it is never compiled into any kernel module on
this system. The actual loaded `ng_iface.ko` module is built from
`sys/netgraph/iface/ng_iface.c` (the legacy netgraph tree), which **already
contains the correct implementation** (reads the AF from the mbuf, not from
`dst->sa_data`).

## Verification

### 1. Which source tree is the loaded module from?

```
$ strings /boot/kernel/ng_iface.ko | grep ng_iface.c
/usr/src/sys/netgraph/iface/ng_iface.c     <-- legacy netgraph, NOT netgraph7
```

The loaded `ng_iface.ko` is from `sys/netgraph/iface/ng_iface.c`. There is no
`netgraph7` module in `/boot/kernel/`:

```
$ ls /boot/kernel/ | grep ng7    # (empty — no netgraph7 modules)
```

`netgraph7` is not compiled into the kernel either (no `NETGRAPH7` in
`sys/config/X86_64_GENERIC`, no `netgraph7` strings in the kernel binary).

### 2. The cited code (netgraph7) — HAS the bug

`sys/netgraph7/iface/ng_iface.c:428-431`:
```c
if (dst->sa_family == AF_UNSPEC) {
    bcopy(dst->sa_data, &af, sizeof(af));   /* reads uninitialized sa_data! */
    dst->sa_family = af;                    /* truncates uint32_t to uint8_t */
}
```
And `sys/netgraph7/iface/ng_iface.c:481`:
```c
KASSERT(family != AF_UNSPEC, ("%s: family=AF_UNSPEC", __func__));
```

This is a real bug: for DLT_NULL BPF writes, `bpf_movein` (sys/net/bpf.c:190-193)
sets `sa_family=AF_UNSPEC` and `hlen=0`, so `sa_data` is never initialized
(the `if (hlen != 0)` block at bpf.c:253 is skipped). The `bcopy` reads 4
bytes of stack garbage. If the low byte is 0, `sa_family` stays `AF_UNSPEC`
and the KASSERT panics.

### 3. The actual loaded code (netgraph) — ALREADY FIXED

`sys/netgraph/iface/ng_iface.c:423-430`:
```c
if (dst->sa_family == AF_UNSPEC) {
    if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL)
        return (ENOBUFS);
    dst->sa_family = (sa_family_t)*mtod(m, int32_t *);  /* reads AF from mbuf! */
    m->m_data += 4;                                       /* strips 4-byte AF prefix */
    m->m_len -= 4;
    m->m_pkthdr.len -= 4;
}
```

This is exactly the fix the finding recommends: read the AF from the leading
4 bytes of the mbuf (DLT_NULL convention) instead of from `dst->sa_data`, and
strip those 4 bytes. The legacy netgraph version already implements this
correctly.

### 4. Cannot create ng_iface for live testing (separate bug)

Even if we wanted to test the legacy module's code path, creating an ng_iface
node panics with a **separate** constructor bug:

```
panic: try holding ifnet lock in netisr   (ng_eiface, same pattern)
panic: trying to free NULL pointer         (ng_iface, same root cause)
```

`ng_mkpeer` processes the creation message in a netisr context, and `if_attach`
called from the constructor panics because `ifnet_lock()` cannot be held from
netisr. This is an unrelated infrastructure bug that prevents creating any
netgraph interface nodes on this guest.

## Conclusion

**NOT REPRODUCED.** The finding audited the wrong source tree. The bug exists
in `sys/netgraph7/iface/ng_iface.c` (dead code, never compiled), but the
loaded `ng_iface.ko` module is from `sys/netgraph/iface/ng_iface.c` which
already has the correct implementation. No runtime impact.

The finding's "Recommended fix" (read AF from mbuf) is already implemented in
the running code. The `netgraph7` version should be fixed if it is ever built,
but it is currently dead code.

## Impact

None — the vulnerable code is not compiled or loaded. The running code is
correct.

## PoC changes

Authored `df-bpf-panic.c` (was missing — only README.md existed in the PoC
folder). The PoC cannot reproduce because:
1. The cited code (`netgraph7`) is dead code (not loaded).
2. The loaded code (`netgraph`) already has the fix.
3. A separate constructor bug prevents creating ng_iface nodes.

## Fix

A `fix.diff` is provided for `sys/netgraph7/iface/ng_iface.c` (the cited file)
to fix the dead code, matching the correct implementation already present in
`sys/netgraph/iface/ng_iface.c`. No fix is needed for the running system.
