{
  "finding_id": "DF-3526",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "Creating the first netgraph7 ng_iface node panics the stock kernel deterministically (3/3 independent boots): panic: trying to free NULL pointer at ng_iface_constructor+0x312. Root cause is the compiler-visible UB pattern in ng_iface_get_unit() (sys/netgraph7/iface/ng_iface.c:296-301): bcopy() of the initially-NULL ng_iface_units maps onto __builtin_memmove, GCC deletes the NULL guard at :300, and the first array growth calls kfree(NULL), which is an unconditional panic even on non-INVARIANTS kernels (kern_slaballoc.c:1406). Proven live and by disassembly of the freshly-built module (reloc +0xd76 memmove -> +0xdce _kfree, no intervening test). ng7 twin of v1 DF-3485; separate file and module set. Trigger is root-only (ng7 ng_socket ngc_attach requires caps_priv_check(SYSCAP_RESTRICTEDROOT), uid 1001 gets EPERM), so impact is a privileged deterministic DoS with no write primitive (kfree validates NULL before touching memory). fix.diff (guard the bcopy call) validated at module level: guard restored in machine code, full mkpeer/GET_IFNAME=ng0/shutdown lifecycle plus 20/20 serial and parallel create/destroy cycles clean.",
  "exploit_chain": "",
  "evidence": "panic.txt (trace _kfree <- ng_iface_constructor+0x312 <- ng_make_node <- ng_apply_item <- ngthread); disasm.stock.txt + reloc.stock.txt (memmove@+0xd76 flows into _kfree@+0xdce, no NULL test); run.log/run.2.log/run.3.log (3/3); unpriv_check.txt (EPERM for uid 1001); disasm.fix26.txt + fix_run.log (fixed module: guard restored, lifecycle + stress clean)",
  "kernel_refs": [
    "sys/netgraph7/iface/ng_iface.c:292",
    "sys/netgraph7/iface/ng_iface.c:296",
    "sys/netgraph7/iface/ng_iface.c:300",
    "sys/sys/systm.h:257",
    "sys/kern/kern_slaballoc.c:1406",
    "sys/netgraph7/socket/ng_socket.c:182"
  ],
  "poc_changes": "None \u2014 harness written fresh for this finding (ng7 control-socket ABI adapted from the DF-3524 pattern); no seed PoC existed.",
  "attempts": 4,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026  root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "runtime_sec": 1800,
  "guest_dirty": 0,
  "build_cmd": "cd /usr/src/sys/netgraph7/netgraph && make; cd ../socket && make; cd ../iface && make; cc -O2 -o /root/poc/iface_con /root/poc/iface_con.c",
  "run_cmd": "kldload /usr/src/sys/netgraph7/netgraph/netgraph.ko; kldload /usr/src/sys/netgraph7/socket/ng_socket.ko; kldload /usr/src/sys/netgraph7/iface/ng_iface.ko; /root/poc/iface_con create",
  "code_hash": "17bee5bb523d4edafdb0c96e86edb4d5c4731549aaf3dcb6933af83e08006fd4",
  "notes": "The task leads SECOND half (v1 DF-3486 if_attach-from-netisr twin) was checked and REFUTED for ng7: ng_snd_item() funnels every refs==1 control message to cpu0s ngthread port (ng_base.c:1956-1961), a kernel-thread context where if_attach()/if_detach() are legal \u2014 empirically the full lifecycle works with only the bcopy fix (fix_run.log). This also serializes all ng7 iface constructors/shutdowns on one thread, so the unsynchronized ng_iface_units bitmap has no concurrent access today. Guest left in clean reset state.",
  "recommended_fix": "Guard the bcopy call with if (ng_iface_units_len > 0) so the NULL-pointer operand never reaches __builtin_memmove and GCC keeps the kfree NULL test (see fix.diff).",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0 (stock kernel; ng_iface module rebuilt with fix.diff only)"
}