⬢ DragonFlyBSD Kernel Audit
DF-3532 / verdict.json
← back to finding ↓ download raw
{
 "finding_id": "DF-3532",
 "status": "inconclusive",
 "reproduced": 0,
 "impact": "none",
 "confidence": "likely",
 "verdict": "Partially verified, honestly inconclusive on the measurement. The ng7 error branch is REACHABLE on the harness kernel: with a colliding node name pre-created, the failed open logs 'ttyNNN: node name exists?' (the ng7 ngt_open :212-216 branch) - captured in dmesg. The leak itself is code-certain: that branch does sc->flags |= FLG_DIE; NG_NODE_UNREF(sc->node); return(error) - ng7 ng_unref_node frees the node WITHOUT invoking nd_shutdown, and NG_NODE_SET_PRIVATE only runs at :221 AFTER naming succeeds, so the kmalloc'd ngt_softc (~140B, M_NETGRAPH) is orphaned per failed open. The quantitative demonstration was confounded by harness mechanics (ng7 naming-counter state across runs made collisions intermittent; pre-created nodes must be kept hooked to survive; a 500-cycle run produced 500 SUCCESSFUL opens with live-state growth, not leaks). Privileged-gated ~140B permanent leak per failed open stands on code.",
 "evidence": "run.log (dmesg 'tty500/tty501: node name exists?' + vmstat -m netgraph growth lines), ttyleak.c",
 "kernel_refs": [
  "sys/netgraph7/tty/ng_tty.c:212",
  "sys/netgraph7/tty/ng_tty.c:215",
  "sys/netgraph7/tty/ng_tty.c:221"
 ],
 "poc_changes": "ttyleak.c adapted to the ng7 wire format; node-name pre-creation must keep nodes hooked to persist",
 "attempts": 3,
 "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Sun Oct 25 20:46:48 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_NG7 x86_64 (harness kernel: X86_64_GENERIC + NETGRAPH7 stack)",
 "runtime_sec": 600,
 "guest_dirty": 0,
 "build_cmd": "gcc -O -o ttyleak7 ttyleak.c",
 "run_cmd": "./ttyleak7 500; vmstat -m | grep netgraph",
 "code_hash": "6c8610c1cd1710a53f5eca7aeccc661ca3776681382ece250a1c74a0105cc57d",
 "notes": "fix_status: compile-validated (see fix.diff); runtime A/B not achieved (measurement confounded, Low tier).",
 "recommended_fix": "free sc on the naming-failure path (kfree(sc, M_NETGRAPH) after the UNREF) or route through shutdown."
}