DF-3484 / verdict.json
{ "finding_id": "DF-3484", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "Not reproduced (statistical race, producers could not be driven at rate through v1 userland on this guest). Code-confirmed by source: the single global ngqbase/ngqlast/ngqfree/ngqsize are mutated under crit_enter() only (ng_base.c:1894-1929, 1936-1947) - a per-CPU critical section that does not exclude other CPUs; the code comments themselves say 'don't worry about races'. Two producers on different CPUs executing the ~10-instruction tail-link window lose one entry permanently (its mbuf/message plus hook/node refs leak). Producer attempts: ng_socket DATA-socket flood path (ngrace.c) - blocked by a v1 ng_socket quirk (ng_connect_data on a named live node returns ENXIO from ng_path2node even though ngctl list shows the node; data sockets cannot be associated from a second process in this environment). Single-producer control 300k sends: no mbuf drift; guest healthy. Leak remains code-certain; window is instructions wide; realistic trigger is a multi-CPU PPPoE/L2TP concentrator under sustained ngintr load, not reproducible in a bounded session.", "evidence": "run.log (ngtrace of association attempts + control run), ngrace.c, source excerpt", "kernel_refs": [ "sys/netgraph/netgraph/ng_base.c:1894", "sys/netgraph/netgraph/ng_base.c:1927", "sys/netgraph/netgraph/ng_base.c:1936" ], "poc_changes": "ngrace.c written fresh; v1 data-socket association (ng_connect_data) failed ENXIO in this environment - flood never launched", "attempts": 4, "guest_uname": "DragonFly dfbsd 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": 120, "guest_dirty": 0, "build_cmd": "gcc -O -o ngrace ngrace.c", "run_cmd": "./ngrace 300000 # single-producer control only", "code_hash": "cb3436749d552dac4242c3e3271e33a57ab3550c5bed3af5de565d64b5f1e010", "notes": "v1 netgraph core IS shipped (netgraph.ko etc. in /boot/kernel); reachability of the queue itself is certain - only the statistical window was not hit.", "recommended_fix": "replace crit_enter-only protection with a spinlock (or per-CPU queues) around ngqbase/ngqlast/ngqfree/ngqsize." } |