{
 "finding_id": "DF-3317",
 "status": "reproduced",
 "reproduced": 1,
 "impact": "panic",
 "confidence": "certain",
 "verdict": "tcp6_ctlinput() dispatches ICMPv6 Packet-Too-Big to tcp_mtudisc() with no sequence-number validation and no RFC 8200 1280-octet minimum-MTU floor (tcp_subr.c:1582-1590, 1626-1630), so an off-path blind forger needs only the victim 4-tuple. A forged PTB with mtu=60 drove t_maxseg/t_maxopd to 0 (verified via net.inet.tcp.pcblist; with timestamp options the negative mss is clamped to garbage t_maxseg=419430), and the next close of that connection executed tcp_subr.c:1013s i = (i + tp->t_maxseg/2)/tp->t_maxseg with t_maxseg==0, producing Fatal trap 18: integer divide fault ... Stopped at tcp_close+0x66e: divq (system-down panic, current process=Idle/netisr; twice reproduced on the stock INVARIANTS kernel; two further runs where the fault hit the closing syscall thread delivered signal 11 to the process). fix.diff adds the RFC-mandated if (arg < IPV6_MMTU) goto out; and was validated by in-guest nativekernel rebuild: patched kernel leaves t_maxseg unchanged (14336) on the identical PoB, close returns cleanly, and legitimate PTB mtu=1300 still shrinks MSS to 1240.",
 "exploit_chain": "remote off-path IPv6 spoofer -> forged ICMPv6 PTB (type 2, mtu=60, garbage th_seq never validated) quoting victim 4-tuple -> icmp6_notify_error -> tcp6_ctlinput:1575-1590 (raw icmp6_mtu) -> in6_pcbnotify -> tcp_mtudisc:1820-1871 -> maxopd=0, t_maxseg=0 (u_int) -> victim closes conn with t_rttupdated>=16 and ssthresh-save block entered -> tcp_close:1013 integer division by t_maxseg==0 -> Fatal trap 18 (#DE) -> kernel panic (system down). No memory-write primitive: impact ceiling is remote unauthenticated kernel panic / persistent per-connection MSS corruption (blind), incl. tiny-MSS amplification for mtu in (60,1279] and DF-0338-class garbage t_maxseg for mtu in [41,59].",
 "evidence": [
  "run.log: after-PTB : t_state=5 t_maxseg=0 t_maxopd=0 on stock kernel #0 (and fix_run.log shows it unchanged on patched #1)",
  "panic.txt / panic_console_full.txt: 12x tcpcb ...: MSS (0) too small to hold options! + Fatal trap 18: integer divide fault while in kernel mode + Stopped at tcp_close+0x66e: divq %r8,%eax + current process = Idle (two fatal reproductions; two signal-11 process-kill variants logged at 17:16:16 and 17:17:53)",
  "fix.diff: the IPV6_MMTU floor in tcp6_ctlinputs PRC_MSGSIZE branch",
  "fix_inspect.log/fix_run.log: patched kernel - t_maxseg 14336 before AND after PTB, close returns rc=0, dmesg MSS(0) count 0",
  "fix_sanity.log: patched kernel still honors legitimate PTB mtu=1300 (t_maxseg 14336->1240)",
  "VERDICT.md: full narrative incl. the raw-socket-is-injection-only privilege-model note"
 ],
 "kernel_refs": [
  "sys/netinet/tcp_subr.c:1575",
  "sys/netinet/tcp_subr.c:1582",
  "sys/netinet/tcp_subr.c:1584",
  "sys/netinet/tcp_subr.c:1626",
  "sys/netinet/tcp_subr.c:1628",
  "sys/netinet/tcp_subr.c:1820",
  "sys/netinet/tcp_subr.c:1852",
  "sys/netinet/tcp_subr.c:1868",
  "sys/netinet/tcp_subr.c:1871",
  "sys/netinet/tcp_subr.c:1013",
  "sys/netinet/tcp_subr.c:945",
  "sys/netinet/tcp_subr.c:1509",
  "sys/netinet6/icmp6.c:1039",
  "sys/netinet6/icmp6.c:1078",
  "sys/netinet/tcp_var.h:223"
 ],
 "poc_changes": "seed PoC assumptions fixed during verification: (1) AF_INET6 SOCK_RAW never transmits a caller-built IPv6 header (kernel prepends its own; raw_ip6.c:392-418 also computes the checksum) - the first build double-headered the packet and died as unknown icmp6 type (96); (2) TCP_NOOPT on the victim socket is required for t_maxseg==0 exactly (with timestamps, mss=0-12=-12 and the unsigned clamp at tcp_subr.c:1868 yields garbage 419430); (3) the ssthresh-save block must be entered at close - seeded via route change -inet6 -host ::1 -ssthresh 1024, modeling the organic cached state of any previously congested connection; (4) SO_LINGER{1,0} close (abort -> tcp_drop -> tcp_close) for a deterministic synchronous teardown; (5) pcblist parsing needs #define _KERNEL_STRUCTURES + sys/socketvar.h + -I/usr/src/sys.",
 "attempts": 8,
 "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": 4500,
 "guest_dirty": 0,
 "build_cmd": "cc -O2 -Wall -I/usr/src/sys -o ptb6 ptb6.c",
 "run_cmd": "route change -inet6 -host ::1 -ssthresh 1024 && ./ptb6 -p 49161  (./ptb6 -x ... for inspect-only)",
 "code_hash": "3ee6c719232761066c8ab4c6818cdbdd293c7debf22b6b7a48b2c667056a0b80",
 "notes": "Root is needed only for local raw-ICMPv6 injection as a stand-in for the off-path forger; the packet is otherwise identical and no local information beyond the 4-tuple is used (th_seq is garbage, proving the missing check). Impact ceiling is remote panic/DoS - t_maxseg corruption is protocol state, not a memory-write primitive, so uid0 escalation is not applicable. Intermediate mtu values give persistent blind MSS corruption of any IPv6 TCP connection. Recommended follow-up hardening beyond fix.diff: copy the quoted th_seq and apply the v4-style [snd_una,snd_max) check (RFC 5927) as tcp_ctlinput:1509-1511 does.",
 "recommended_fix": "tcp6_ctlinput PRC_MSGSIZE: discard Packet-Too-Big with next-hop MTU < IPV6_MMTU (RFC 8200 5.2 MUST); follow up with v4-style quoted-sequence validation",
 "fix_status": "fixed",
 "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Thu Sep 10 17:27:19 UTC 2026   root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
 "fix_baseline_reproduced": 1,
 "fix_patched_reproduced": 0,
 "fix_verdict": "fix.diff (IPV6_MMTU floor) applied to /usr/src in-guest, make nativekernel + installkernel, reboot into #1. Identical PoC on patched kernel: after-PTB t_maxseg unchanged (14336/16324 vs 0 on baseline), zero MSS (0) dmesg entries, aborting close returns rc=0, guest healthy; legitimate PTB mtu=1300 still shrinks MSS to 1240 (PMTUD preserved). Baseline panic reproduced twice on stock #0 prior.",
 "fix_evidence": "fix_inspect.log, fix_run.log, fix_sanity.log, fix_build.log.tail, fix.diff"
}