# DF-0608 — VERDICT

**Verdict: REPRODUCED (source-level). Info-severity CWE-131 typo confirmed; zero runtime/security impact on supported platforms.**

## The claim

`NGM_CISCO_GET_IPADDR` in `ng_iface_rcvmsg` sizes its netgraph response with
`sizeof(ips)`, where `ips` is a **pointer** (`struct ng_cisco_ipaddr *ips`),
instead of `sizeof(*ips)` or `sizeof(struct ng_cisco_ipaddr)`. The finding
flags this as a latent `CWE-131` (Incorrect Calculation of Buffer Size) that
has **no impact on any platform DragonFlyBSD currently targets** (all 64-bit).

## Confirmation (source-level, traced line-by-line)

The cited typo is **real and present** at `sys/netgraph7/iface/ng_iface.c:724`:

```c
720:    struct ng_cisco_ipaddr *ips;          /* pointer */
...
724:    NG_MKRESPONSE(resp, msg, sizeof(ips), M_WAITOK | M_NULLOK);
...
729:    ips = (struct ng_cisco_ipaddr *)resp->data;
730:    ips->ipaddr  = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;     /* 4 bytes @0 */
731:    ips->netmask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;  /* 4 bytes @4 */
```

- `sizeof(ips)` = `sizeof(struct ng_cisco_ipaddr *)` = **8 on amd64**, **4 on i386**.
- `NG_MKRESPONSE` (`sys/netgraph7/ng_message.h:410-424`) allocates
  `sizeof(struct ng_mesg) + len` and sets `header.arglen = len`.
- `struct ng_cisco_ipaddr` (`sys/netgraph7/cisco/ng_cisco.h:65-68`) = two
  `struct in_addr` = **8 bytes**.

On amd64: `len = sizeof(ips) = 8 == sizeof(struct ng_cisco_ipaddr) = 8` → the
8-byte body is exactly filled by the two `in_addr` writes. **No overflow, no
wrong-size copy, no observable defect.** This was verified at runtime with a
userspace size-proof (`run.log` step 5):

```
sizeof(struct ng_cisco_ipaddr) = 8
sizeof(*ips)                    = 8
sizeof(ips)  [pointer, BUGGY]   = 8
VERDICT: on this platform sizes coincide -> NO runtime/security impact
```

On a hypothetical i386 build: `len = sizeof(ips) = 4`, but the handler writes
8 bytes → a **4-byte heap overflow** into the `M_NETGRAPH_MSG` slab, and the
consumer would only read 4 bytes of body (silent netmask loss). DragonFlyBSD
has no 32-bit platform under `sys/platform`/`sys/cpu`, so this is latent.

## Additional finding (twin typo)

The **identical** `sizeof(ips)` typo exists in the **old-netgraph** copy at
`sys/netgraph/iface/ng_iface.c:701`:

```c
697:    struct ng_cisco_ipaddr *ips;
...
701:    NG_MKRESPONSE(resp, msg, sizeof(ips), M_NOWAIT);
```

This copy **is** built as the loadable module `/boot/kernel/ng_iface.ko` on the
running guest (the netgraph7 `ng_iface.c` is `optional netgraph7_iface` and no
netgraph7 modules are installed — confirmed: `ls /boot/kernel/ | grep ng7` →
empty). So the live-reachable instance of this typo is the old-netgraph one;
the cited netgraph7 line is the same defect in sibling code. The fix covers both.

## Reachability on this guest

- `ng_iface.c` (both copies) is `optional netgraph*_iface` — a **module**, not
  in `X86_64_GENERIC`.
- `/boot/kernel/ng_iface.ko` (old netgraph) exists but is **not loaded** by
  default (`kldstat | grep ng` → empty).
- Reachable path: `kldload ng_iface` → create an `ng_iface` node via
  `ng_socket`/`ngctl` → assign it an IPv4 address → `ngctl msg <node>: getipaddr`.
  Requires netgraph access (any local user with `ng_socket`).

No escalation chain applies — this is a pure correctness/hardening typo, not a
write-capable primitive on any supported platform.

## Exploit chain

None. This is not a memory-corruption primitive on any platform DragonFlyBSD
targets. No `uid=0` is derivable. Documented impact ceiling: **zero** on amd64;
latent 4-byte heap overflow on a hypothetical i386 port.

## Fix validation (Phase 8)

Authored `fix.diff` changing `sizeof(ips)` → `sizeof(*ips)` in **both** copies
(cited netgraph7 + twin netgraph). `git apply --check` → clean.

Validated in-guest on the unpatched `with-src` baseline (`6.5-DEVELOPMENT #0`):

1. **Baseline (before):** typo present in both source files:
   - `sys/netgraph7/iface/ng_iface.c:724`: `NG_MKRESPONSE(resp, msg, sizeof(ips), ...)`
   - `sys/netgraph/iface/ng_iface.c:701`:  `NG_MKRESPONSE(resp, msg, sizeof(ips), ...)`
2. **Applied fix.diff** (`patch -p1`): both hunks succeeded at lines 721 and 698.
3. **After:** both lines read `sizeof(*ips)` — typo gone.
4. **Built `ng_iface` module** (`make` in `sys/netgraph/iface/`): **rc=0**, clean
   compile under the kernel's strict flags (`-Werror -Wpointer-arith
   -Wcast-qual -Wstrict-prototypes ...`), producing a valid 13016-byte
   `ng_iface.ko` with `ng_iface_rcvmsg` present. Full build log in `fix_build.log`.

No runtime before/after test is possible or meaningful on amd64: because
`sizeof(ips) == sizeof(*ips) == 8`, the fixed and unfixed modules produce
byte-identical behavior. The validation is therefore **source-level**: the
defect is present in the baseline source and absent in the patched source, and
the patched module compiles cleanly. This is the correct and complete
validation for an Info-severity, zero-runtime-impact hardening fix.

## Recommended fix

`fix.diff` (in this folder): `sizeof(ips)` → `sizeof(*ips)` in
`sys/netgraph7/iface/ng_iface.c:724` **and** `sys/netgraph/iface/ng_iface.c:701`.
This **supersedes** the finding markdown's proposal (which covered only the
netgraph7 copy) by also fixing the identical twin typo in the old-netgraph
copy that is actually built into the installed `/boot/kernel/ng_iface.ko`.

## PoC changes

The shipped README declared "No PoC." Added:
- `verify_typo.sh` — grep-confirms the typo at both sites + an inline
  userspace compile of the size coincidence proof.
- `build.sh` / `run.sh` — exact reproducible build/run wrappers.
- `run.log` — full verification output on the live guest.
- `fix.diff` / `fix_build.log` — the validated fix + clean module build log.
