{
  "finding_id": "DF-4342",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Deterministic logic defect, verified line-by-line against the source; not exercisable on the audit guest because the mn netgraph surface cannot exist there (no 0x110a PCI device, if_mn optional mn netgraph absent from GENERIC, kldload ENOENT). ngmn_newhook admits a second hook on an existing channel whenever its state is DOWN (if_mn.c:470-473), silently overwriting sc->ch[chan]->hook/ts (474-475) and double-incrementing nhooks (478); ngmn_connect then reports silent success for the second hook (664-665); the first ngmn_disconnect tears the shared channel down under the still-connected second hook (756-794) whose own disconnect early-returns before the nhooks decrement (756-758 vs 795), permanently wedging ngmn_config line changes (308-310) and blackholing the second hooks traffic. Two distinct hook names provably alias one channel (E1: ffs(ts)-1 for ts2 vs ts2-3; E1U: hardcoded chan=1) and the netgraph core keys hooks by name only (ng_base.c:697-763). Concurrent rmhook of the two aliased hooks double-frees both descriptor rings (no serialization; mn_free_desc clobbers dp->vnext with the freelist head at if_mn.c:498-503, so the losing walker frees live descriptors of other channels).",
  "exploit_chain": "root ngctl: mkpeer ts2; mkpeer ts2-3 (aliases chan 2, accepted while DOWN); connect both (second silent); rmhook ts2 -> full teardown under live ts2-3 hook; ts2-3 blackholed; textconfig line e1u refused forever (nhooks stuck). Concurrent variant: rmhook ts2 & rmhook ts2-3 & -> both teardowns pass the DOWN check -> double-free of every trxd + m_freem of every mbuf -> M_MN pool corruption. Not runnable on this guest (hardware absent).",
  "evidence": "VERDICT.md (7-step deterministic trace); README.md (code excerpts); trigger_alias.sh; run.log + env_guest.txt (surface absent); fix.diff (hook-ownership guard, git apply --check OK)",
  "kernel_refs": [
    "sys/dev/netif/mn/if_mn.c:470",
    "sys/dev/netif/mn/if_mn.c:474",
    "sys/dev/netif/mn/if_mn.c:475",
    "sys/dev/netif/mn/if_mn.c:478",
    "sys/dev/netif/mn/if_mn.c:466",
    "sys/dev/netif/mn/if_mn.c:664",
    "sys/dev/netif/mn/if_mn.c:756",
    "sys/dev/netif/mn/if_mn.c:758",
    "sys/dev/netif/mn/if_mn.c:795",
    "sys/dev/netif/mn/if_mn.c:308",
    "sys/dev/netif/mn/if_mn.c:498",
    "sys/netgraph/netgraph/ng_base.c:697"
  ],
  "poc_changes": "trigger written fresh (no seed)",
  "attempts": 1,
  "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": 18,
  "guest_dirty": 0,
  "build_cmd": "n/a (kernel driver, optional mn netgraph; not present on guest)",
  "run_cmd": "./run.sh guest  (see run.log)",
  "code_hash": "",
  "notes": "Hardware-gated + root; deterministic logic corruption (nhooks drift, admin DoS, silent data blackhole) plus double-free enabler together with the missing serialization of DF-4341.",
  "recommended_fix": "Gate ngmn_newhook on sc->ch[chan]->hook != NULL instead of state==UP, and clear sch->hook in ngmn_disconnect (fix.diff; also closes DF-1540 at the writer side)",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "No baseline on this guest (hardware absent). fix.diff is line-accurate (git apply --check clean) and closes both the aliasing admission and the dangling sch->hook left behind (DF-1540 writer side).",
  "fix_evidence": "findings/poc/DF-4342/fix.diff"
}