{
  "finding_id": "DF-3389",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "Reproduced as a natural race on the stock-config INVARIANTS guest: ip6_setdstifaddr (ip6_input.c:796-805) stores an uncounted in6_ifaddr pointer into the PACKET_TAG_IPV6_INPUT m_tag; the terminal-header defer (ip6_input.c:739-755) hands the packet to transport6_processing_handler on netisr-0, whose consumers dereference ia6_flags (tcp_input.c:624-625, 1069-1076) after the address purge freed the object. A poison canary in ifac_free (0xDF3389A6 written to ia6_flags of every freed in6_ifaddr plus a pointer ring, checked on every deferred packet) confirmed 4 UAF reads across two independent 300 s full-rate races (683k and 824k add/delete cycles; 1.7-1.8M SYNs each; unpriv user traffic vs root purge). Controls: static address for 240 s gave 18,044,945 captured-and-deferred packets and ZERO hits; throttled cycling (~508 c/s) gave zero hits. Impact ceiling is honest and limited: a read of freed heap memory driving a branch (spurious ICMPv6 unreachable / deprecated-address RST, i.e. connection-level misbehavior) with panic potential under slab reuse or INVARIANTS-adjacent container states; no write primitive and no value reaches userspace, so no escalation path. Fix (fix.diff) replaces the pointer with a u_int32_t ia6_flags snapshot taken at store time and switches all three consumers to the snapshot; the fixed kernel was built clean and survived the identical race shape twice with zero anomalies while IPv6 TCP/ICMPv6 behaved normally. Unrelated bug observed during verification: full-rate SIOCDIFADDR_IN6 cycling panics stock kernels in nd6_timer_dispatch (rt_llinfo != ln) - separate finding recommended.",
  "exploit_chain": "",
  "evidence": "logs/run1-race-output.txt (3 UAF-HITs, counters 3/1523/1523), logs/run3-dmesg.txt (1 UAF-HIT ia6=0xfffff8004f31bde0 on fresh boot), logs/control-staticaddr.txt (18,044,945 defers, 0 hits), logs/fix-validation.txt (fixed kernel: 505k cycles + 1.06M SYNs race clean, guest up), df3389_canary.diff (poison instrumentation), fix.diff (validated fix), env.txt",
  "kernel_refs": [
    "sys/netinet6/ip6_input.c:490",
    "sys/netinet6/ip6_input.c:534-536",
    "sys/netinet6/ip6_input.c:739-755",
    "sys/netinet6/ip6_input.c:776-790",
    "sys/netinet6/ip6_input.c:796-805",
    "sys/netinet6/ip6_var.h:271",
    "sys/netinet/tcp_input.c:624-629",
    "sys/netinet/tcp_input.c:1069-1076",
    "sys/netinet6/in6.c:2304-2353",
    "sys/netinet6/in6.c:1290-1337",
    "sys/net/if.c:3466-3491",
    "sys/net/if.c:3520-3590",
    "sys/net/route.c:285-309",
    "sys/net/netisr2.h:84-128"
  ],
  "poc_changes": "Harness written from scratch (no seed pack existed). flooder.c: batched nonblocking connects (blocking connect stalls ~75 s when the address flaps mid-SYN). cycler.c: direct SIOCAIFADDR_IN6/SIOCDIFADDR_IN6 ioctls (fork/exec ifconfig too slow), infinite lifetimes to silence per-add syslog. stretch.c: RFC3542 HBH/DSTOPTS attach is EPERM for unpriv on DragonFly - stretcher degraded to plain UDPv6 (still exercises store+defer). Canary kernel required two compile fixes vs the draft (-Wmissing-prototypes forward decl, -Wnested-externs file-scope extern).",
  "attempts": 8,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Tue Oct 20 19:50:24 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 (canary) / #1: Tue Oct 20 20:35:08 UTC 2026 (fixed); stock #0 Thu Jul 2 06:02:54 UTC 2026",
  "runtime_sec": 7800,
  "guest_dirty": 0,
  "build_cmd": "guest: cc -O2 -o cycler cycler.c && cc -O2 -o flooder flooder.c && cc -O2 -o stretch stretch.c; kernel: cd /usr/src && patch -p1 < df3389_canary.diff && make -j6 nativekernel KERNCONF=X86_64_GENERIC && make installkernel",
  "run_cmd": "guest root: sysctl net.inet6.ip6.dad_count=0 && sh /root/df3389/race.sh 300 3 && sysctl net.inet6.ip6.df3389_hits && dmesg | grep UAF-HIT",
  "code_hash": "9ae2d96e7062bd3f8c1172e69f57364584007877ad6d5832d5c0c343f5d96e14",
  "notes": "Hit rate honest: 3 hits in run 1 and 1 in run 3 (full-rate ~2.3-2.7k cycles/s); 0 at ~508 c/s in 300 s; 0 in 18M-exposure static control. The nd6_timer rt_llinfo!=ln panic from full-rate cycling (stock and canary kernels) is a SEPARATE root-triggered bug; evidence captured, own finding recommended. Guest reset to clean with-src snapshot after validation.",
  "recommended_fix": "Snapshot ia6_flags into struct ip6aux at ip6_setdstifaddr time instead of storing the in6_ifaddr pointer; consumers use ip6_getdstifaddr_flags() (fix.diff, build- and race-validated)."
}
