{
 "finding_id": "DF-3358",
 "status": "reproduced",
 "reproduced": 1,
 "impact": "dos",
 "confidence": "certain",
 "verdict": "Any local unprivileged user permanently consumes kernel memory by writing RTM_GET messages carrying unique RTA_GENMASK sockaddrs to a PF_ROUTE socket: route_output() (sys/net/rtsock.c:742-748) installs genmasks globally for every message type, including the one type (RTM_GET) exempted from the privilege check at :738-740. Each unique mask allocates 128B per CPU (rn_addmask, sys/net/radix.c:587) into never-shrinking per-CPU mask trees; masks have no free path. Verified as uid 1001 on the stock INVARIANTS guest: 100k messages -> routetbl 234 -> 586K allocs / +73.3MB in 9.2s; same-mask control -> zero growth; sustained to the 390M M_RTABLE type limit (ENOBUFS at iteration 532,426) after which root cannot add routes (routing table overflow), getifaddrs fails inside route(8), and arpresolve cannot allocate llinfo for new neighbors until reboot. fix.diff (require SYSCAP_RESTRICTEDROOT for genmask-carrying RTM_GET) validated on a rebuilt kernel: unpriv gets EPERM with zero growth, root installs unchanged (+58.8K/10k msgs), unpriv plain RTM_GET unchanged.",
 "exploit_chain": "",
 "evidence": [
  "findings/poc/DF-3358/run.log \u2014 100k unique-mask run: routetbl 234/38.0K -> 586K/73.3M in 9.2s as uid 1001; control (20k same-mask) shows zero growth",
  "findings/poc/DF-3358/run.2.log \u2014 600k run: ENOBUFS at iteration 532,426, routetbl pinned at 3.05M allocs / 390M (type limit)",
  "findings/poc/DF-3358/run.3.log \u2014 post-exhaustion: route add fails as root (routing table overflow), arpresolve/arplookup llinfo failures, recovery = reboot only",
  "findings/poc/DF-3358/fix.run.log \u2014 patched kernel (#1 Sep 11 09:08:32): unpriv PoC -> EPERM at iter 0, routetbl unchanged 234/38.0K; root control +58.8K/7.36M per 10k; unpriv plain RTM_GET write=168 no EPERM",
  "findings/poc/DF-3358/rtmask_poc.c \u2014 PoC source (sha256 45b50d3e...)",
  "findings/poc/DF-3358/fix.diff \u2014 one-hunk privilege gate, applied+validated in-guest"
 ],
 "kernel_refs": [
  "sys/net/rtsock.c:738-748",
  "sys/net/rtsock.c:750-757",
  "sys/net/route.c:1762-1806",
  "sys/net/route.c:1776-1792",
  "sys/net/radix.c:546-632"
 ],
 "poc_changes": "none \u2014 pack authored fresh in this run (no seed); PoC built unmodified on the guest",
 "attempts": 3,
 "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": 62,
 "guest_dirty": 1,
 "build_cmd": "cc -O2 -Wall -o /tmp/rtmask_poc /tmp/rtmask_poc.c",
 "run_cmd": "/tmp/rtmask_poc 100000     # as unprivileged uid; then: vmstat -m | grep routetbl",
 "code_hash": "45b50d3eb76058ea796ff173af9e0ac2495f2dd0ea838fb75efb9a704873ba1d",
 "notes": "runtime_sec = decisive exploit runs only (9.2s growth + 51.2s to the 390M ceiling); full Phase V incl. fixed-kernel rebuild/validation ~45min. 6-CPU guest: 768B consumed per message (128B x 6 CPUs). Not a corruption primitive (all allocations in-bounds, simply never freed) so no uid0 chain exists; impact ceiling is routing-plane exhaustion requiring reboot. Guest reset (with-src) performed after validation.",
 "recommended_fix": "Require caps_priv_check(SYSCAP_RESTRICTEDROOT) when an RTM_GET carries an RTA_GENMASK before calling rtmask_add_global (see fix.diff)",
 "fix_status": "fixed",
 "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Fri Sep 11 09:08:32 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 applied to guest /usr/src/sys/net/rtsock.c, make -j6 nativekernel + installkernel + reboot. Baseline (stock #0): +73.3MB/100k msgs unpriv, ceiling 390M, routing bricked. Patched (#1): unpriv unique-genmask PoC denied EPERM at iteration 0 with routetbl unchanged (234/38.0K); root genmask installs still work (+58.8K allocs/7.36M per 10k msgs); unprivileged plain RTM_GET without genmask still succeeds (write=168, not EPERM). Bad behavior eliminated, no compatibility regression.",
 "fix_evidence": "findings/poc/DF-3358/fix.run.log; findings/poc/DF-3358/env.txt (both unames); findings/poc/DF-3358/fix.diff"
}