# DF-3506 - VERDICT

**status: reproduced | reproduced: 1 | impact: leak | confidence: certain**

REACHABILITY DISCOVERY THAT GATES ALL FOUR v1-fec FINDINGS: the shipped stock ng_fec.ko cannot create a node at all - ng_fec_constructor deterministically panics 'trying to free NULL pointer' in _kfree on the FIRST node creation (reproduced 2/2 fresh boots, boot.log evidence). Root cause (disassembly + instrumented rebuild on the guest): gcc deletes the 'if (ng_fec_units != NULL)' guard before kfree() in ng_fec_get_unit() because the preceding bcopy(ng_fec_units, ..., 0) passes NULL as a pointer argument - undefined behavior that lets the compiler prove the pointer non-NULL; the instrumented module printed 'FECDBG: ctor enter ng_fec_units=0 len=0' followed by 'FECDBG: get_unit freeing old units 0' - the guard taken on a NULL value, proving the compiler-eliminated check. This panic is not INVARIANTS-gated (plain NULL check in _kfree), so the module is dead on ANY kernel config; the reported rcvmsg/addport/delport/tick paths are unreachable on stock bits. VERIFICATION ON A MINIMALLY-REPAIRED HARNESS MODULE (only fix: skip the len==0 bcopy; rcvmsg/addport/ifunit verbatim, driven from a sysctl context because control messages additionally hit the INVARIANTS-only 'ifnet lock in netisr' assert): with arglen=8 and data 'AAAAAAAA' (no NUL) the kernel log shows 'fec0: tried to add iface AAAAAAAAXXXX' - the %s/strcmp walk read FOUR BYTES past the 8-byte message data into the groomed adjacent heap (same-handler groom of 12 'X' bytes for deterministic magazine reuse). With arglen=4 'CCCC' the read of the NUL terminator itself is provably out of bounds (in-bounds bytes are all 'C'). Bounded-by-first-zero heap over-read, root-gated; fault-grade only at slab/page boundaries; dmesg disclosure of adjacent heap content. FIX VALIDATED A/B on the stock kernel: with fix.diff applied (arglen>=2 + NUL required, same ctor repair), the identical attack with CONFIRMED chunk reuse (oob groom=...msg=... same=1 - the message landed on the groomed chunk) returns EINVAL(22) and prints NO 'tried to add' line at all - the string walk never starts; baseline prints AAAAAAAAXXXX. panic.txt (fresh clean boot) captures the stock-module constructor panic.

## Kernel references
- sys/netgraph/fec/ng_fec.c:1172
- sys/netgraph/fec/ng_fec.c:1177
- sys/netgraph/fec/ng_fec.c:345
- sys/netgraph/fec/ng_fec.c:348
- sys/netgraph/fec/ng_fec.c:272

## Evidence
fec-sequence.log line 'tried to add iface AAAAAAAAXXXX' (4-byte overread visible), fec-boot-final.log (stock-module ctor panic), fechg.c (harness: verbatim rcvmsg/addport + ctor-UB fix, disclosed), FECDBG instrumented prints

## Recommended fix
validate arglen>=2 and memchr(msg->data,'\0',arglen) before treating msg->data as a string in NGM_FEC_ADD_IFACE/DEL_IFACE (also fix the get_unit bcopy UB so the module can build).

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
