SHIPPED /boot/kernel/ng_iface.ko (built from the tree's ng_iface.c, stock flags) objdump -dr --disassemble=ng_iface_constructor -- the inlined ng_iface_get_unit() array-extension path. Relocations prove the callee identity. 588: e8 00 00 00 00 callq 58d # reloc 0x589: _kmalloc (newarray) 58d: 48 85 c0 test %rax,%rax 590: 0f 84 ac 00 00 00 je 642 # ENOMEM path 596: 4c 63 15 00 00 00 00 movslq 0x0(%rip),%r10 # reloc: .bss-4 = ng_iface_units_len 59d: 4c 8b 0d 00 00 00 00 mov 0x0(%rip),%r9 # reloc: .bss+4 = ng_iface_units 5a4: 48 89 c7 mov %rax,%rdi # rdi = newarray 5af: 4c 89 ce mov %r9,%rsi # src = ng_iface_units 5b6: 4c 89 da mov %r11,%rdx # len 5c5: e8 00 00 00 00 callq 5ca # reloc 0x5c6: memmove (bcopy) 5e0: 7e 2d jle 60f # fill loop skipped/... 600: c7 02 ff ff ff ff movl $0xffffffff,(%rdx) # newarray[i] = ~0 60a: 48 39 d0 cmp %rdx,%rax 60d: 75 f1 jne 600 60f: 48 c7 c6 00 00 00 00 mov $0x0,%rsi # reloc 0x612: M_NETGRAPH 616: 4c 89 cf mov %r9,%rdi # *** rdi = ng_iface_units *** 61d: e8 00 00 00 00 callq 622 # reloc 0x61e: _kfree ^ return addr = +0x3a2 = the panic frame >>> THERE IS NO NULL TEST between the load at 59d and the call at 61d. >>> The source-level guard `if (ng_iface_units != NULL)` (ng_iface.c:294) >>> does not exist in the binary. First call has ng_iface_units == NULL >>> => kfree(NULL) => panic("trying to free NULL pointer") >>> (sys/kern/kern_slaballoc.c:1406-1407). Why GCC may drop the guard is documented in-tree: sys/sys/systm.h:257-260 /* ... the following ... * assumes that (to) and (from) cannot be NULL (even when (len) might * be 0), and will optimize-out later NULL tests on (to) or (from). */ #define bcopy(from, to, len) __builtin_memmove(...) bcopy(ng_iface_units, ...) at ng_iface.c:290 makes GCC treat ng_iface_units as provably non-NULL afterwards, so the test at :294 is dead code. Rebuilding the module from the unmodified tree reproduces the identical unguarded pattern (verified 2026-09-13), i.e. this is the current tree's compiled behavior, not a stale binary.