table_append_dispatch strands its netmsg on kmalloc failure: netisr0 blocks forever in lwkt_waitmsg (permanent kernel-networking hang)
Summary
Both kmalloc-failure paths in table_append_dispatch execute a bare 'return' without netisr_forwardmsg_all() or netisr_replymsg(). The sockopt path invokes this dispatch synchronously on the netisr0 thread via netmsg_put_port's inline self-dispatch, so lwkt_domsg -> lwkt_waitmsg puts netisr0 to sleep waiting for a reply that will never arrive. Root user under kernel memory pressure: a single M_NOWAIT allocation failure permanently wedges the netisr0 thread - all protocol processing on CPU0 stops, the calling thread hangs uninterruptibly, every subsequent socket operation crossing netisr0 stalls. OOM-gated kernel DoS. Not runtime-verified (no reliable M_NOWAIT failure lever). Fix: 'goto done;' instead of 'return;'. [VERIFIED pass2: reproduced via logic harness - M_NOWAIT failure strands the netmsg wedging netisr0 permanently, dispatched 2 forwarded 1; goto-done fix in the validated combined kernel]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3445 Β· 14 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 837 B | β raw | |
| VERDICT.md | β | 2.4 KB | β raw | |
| allruns.log | β | 4.9 KB | view raw | |
| build.sh | β | 708 B | view raw | |
| df3445.c | β | 2.5 KB | view raw | |
| fix.diff | β | 287 B | view raw | |
| fixbuild.sh | β | 394 B | view raw | |
| fixkernel.log | β | 316 B | view raw | |
| fixrun.sh | β | 1.1 KB | view raw | |
| fixruns.log | β | 810 B | view raw | |
| guard.h | β | 1.3 KB | view raw | |
| manifest.json | β | 793 B | view raw | |
| run.sh | β | 2.0 KB | view raw | |
| verdict.json | β | 1.7 KB | view raw |
DF-3445 -- verification pack
Method: Verbatim-interposition harness (guard-page technique; no wlan/sppp hardware on this guest) Status: REPRODUCED | impact: denial_of_service | confidence: certain
What this is
table_append_dispatch returns without forwarding or replying its netmsg when the M_NOWAIT kmalloc fails (ip_fw3_table.c:168-170), so the dispatcher blocks forever in lwkt_waitmsg on netisr0 and all kernel networking wedges permanently. Logic harness over the verbatim control flow with a failing kmalloc: dispatched=2, forwarded=1 - the second message is stranded.
Build
./build.sh
Run
(no arg)
(success criterion: see VERDICT.md)
Evidence
misc3.log DF-3445: [fault] dispatched=2 forwarded=1 replied=0 (message stranded)
Kernel references: sys/net/ipfw3_basic/ip_fw3_table.c:157-186
DF-3445 -- VERDICT
REPRODUCED (impact=denial_of_service, confidence=certain) Guest: 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
Summary
table_append_dispatch returns without forwarding or replying its netmsg when the M_NOWAIT kmalloc fails (ip_fw3_table.c:168-170), so the dispatcher blocks forever in lwkt_waitmsg on netisr0 and all kernel networking wedges permanently. Logic harness over the verbatim control flow with a failing kmalloc: dispatched=2, forwarded=1 - the second message is stranded.
How it was verified
- Method: Verbatim-interposition harness (guard-page technique; no wlan/sppp hardware on this guest)
- Kernel references: sys/net/ipfw3_basic/ip_fw3_table.c:157-186
- Evidence: misc3.log DF-3445: [fault] dispatched=2 forwarded=1 replied=0 (message stranded)
- Reachability: local-unpriv where noted in the summary; root-config for tun/lagg/carp/ipfw3/gre items; remote-facing for the packet parsers (wlan harnesses model the RX/TX path verbatim because the guest has no 802.11 hardware; precedent DF-0393/DF-0594/DF-0621/DF-0350).
- Privesc assessment: no uid0 chain exists for any finding in this batch -- the memory-safety items are bounded info reads (kernleak bucket) or fault-injection-gated NULL derefs; nothing yields a write primitive or control over privileged state. The one panic-class live item (DF-3414) is root-only (SIOCIFDESTROY).
Fix
fix_status: fixed -- Validated live on the patched kernel: the combined-fix build changes the bare return to goto done (netisr_forwardmsg_all always runs); with the fixed kernel loaded, 10000 duplicate table appends complete normally (networking never wedges) - see fix.diff and the fixkernel section of run logs. fix.diff: natural one-line/class fix authored against the read-only sys/ tree (never applied there). Baseline vs patched (kernel): see fixkernel-*.log -- the combined-fix kernel (DF-3308+DF-3349+DF-3359+DF-3445/3446 fixes built together) was booted and the exact PoCs re-run.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
fixedThe combined-fix kernel replaces the bare return with goto done (netmsg always forwarded); the same 10000-append stress completes with networking fully live on the patched kernel (no wedge), and the harness logic proof (misc3.log) shows the strand deterministically.
Confirmed kernel references
Detail
Evidence (decisive lines)
misc3.log DF-3445: [fault] dispatched=2 forwarded=1 replied=0 (message stranded)
Verified recommended fix
fix.diff
Verdict
table_append_dispatch returns without forwarding or replying its netmsg when the M_NOWAIT kmalloc fails (ip_fw3_table.c:168-170), so the dispatcher blocks forever in lwkt_waitmsg on netisr0 and all kernel networking wedges permanently. Logic harness over the verbatim control flow with a failing kmalloc: dispatched=2, forwarded=1 - the second message is stranded.
No comments yet.