β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-3505

NGM_KSOCKET_INTERNAL_UPCALL is spoofable by any netgraph control-plane sender: out-of-band forced upcall invocation, widening the known DF-0511 teardown race into a hammerable window

Summary

The internal cookie/command exists so the node can re-run its upcall after hook creation, but rcvmsg accepts it from ANY sender with no origin check - any control-plane user can spam upcall invocations against arbitrary ksocket nodes (the cmdlist even exports 'upcall'). Each invocation calls (*priv->so->so_upcall) out-of-band; combined with node shutdown timing this turns the DF-0511 stale-socket race from a narrow window into a reliably-hammerable primitive (one thread floods INTERNAL_UPCALL, another triggers NGM_SHUTDOWN). v1-only (ng7 replaced the mechanism with kernel-private items). Fix: drop from the externally reachable cmdlist / verify self-queue origin. [VERIFIED pass2: reproduced - 4.5M foreign INTERNAL_UPCALL invocations accepted with no origin check; DF-0511 widening REFUTED node queue serializes upcall vs shutdown]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3505 Β· 9 files
FileTypeDescriptionSize
README.md β€” 590 B ↓ raw
VERDICT.md β€” 1.9 KB ↓ raw
env.txt β€” 309 B view raw
fix.diff β€” 300 B view raw
ksflood.c β€” 5.5 KB view raw
kshold.c β€” 2.7 KB view raw
manifest.json β€” 716 B view raw
run.log β€” 501 B view raw
verdict.json β€” 2.3 KB view raw

DF-3505 - v1 ksocket INTERNAL_UPCALL spoofable

Build: gcc -O -pthread -o ksflood ksflood.c; gcc -O -o kshold kshold.c Run: ./kshold & ; ./ksflood 100 Observed: foreign control-plane sender's NGM_KSOCKET_INTERNAL_UPCALL accepted; 4,540,418 out-of-band upcall invocations processed; 100 shutdown cycles under flood -> NO panic (control messages serialize on the node queue; the DF-0511 widening claim is refuted; the missing-origin-check itself is reproduced).

Kernel: 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

VERDICT.md
↓ download raw

DF-3505 - VERDICT

status: reproduced | reproduced: 1 | impact: none | confidence: certain

The spoof itself is reproduced; the claimed race-widening is refuted. (1) A ksocket node (ks0, inet/dgram/udp, bound) was created and held by a control-plane socket; a FOREIGN sender on a separate AF_NETGRAPH control socket then sent NGM_KSOCKET_INTERNAL_UPCALL (cookie 0x38309f8e, cmd 1) through the hook - v1 ng_ksocket rcvmsg (:848-854) performs no origin check whatsoever and invokes (*priv->so->so_upcall)(so, so->so_upcallarg, M_NOWAIT) out-of-band; 4,540,418 such foreign invocations were accepted in the hammer phase (flood_count, ksflood.c). The command is also exported in the public cmdlist. (2) HOWEVER the DF-0511-widening claim does not hold: both INTERNAL_UPCALL and NGM_SHUTDOWN are control messages and are dequeued strictly serially by the node's input queue, so an upcall flood cannot interleave with rmnode's so_upcall=NULL/soclose - 100 shutdown cycles under a 4.5M-send flood produced no panic and no anomaly. Net assessment: real missing-authorization (any hook-holding node can force out-of-band upcalls on the ksocket), no demonstrated memory-safety consequence on v1; hardening-grade.

Kernel references

Evidence

run.log (ksflood output: bind, SPOOF-UPCALL acceptance, hammer done line with flood_count), ksflood.c, kshold.c

remove NGM_KSOCKET_INTERNAL_UPCALL from the externally reachable cmdlist and verify the message was self-queued (retaddr check) before acting.

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

not_testable
↓ fix.diffper-fix-DF-3505

Confirmed kernel references

Detail

Evidence (decisive lines)

run.log (ksflood output: bind, SPOOF-UPCALL acceptance, hammer done line with flood_count), ksflood.c, kshold.c

PoC changes

written fresh (kshold.c graph holder via generic NGM_MKPEER/NGM_NAME; ksflood.c spoof+hammer)

Verified recommended fix

remove NGM_KSOCKET_INTERNAL_UPCALL from the externally reachable cmdlist and verify the message was self-queued (retaddr check) before acting.

Verdict

The spoof itself is reproduced; the claimed race-widening is refuted. (1) A ksocket node (ks0, inet/dgram/udp, bound) was created and held by a control-plane socket; a FOREIGN sender on a separate AF_NETGRAPH control socket then sent NGM_KSOCKET_INTERNAL_UPCALL (cookie 0x38309f8e, cmd 1) through the hook - v1 ng_ksocket rcvmsg (:848-854) performs no origin check whatsoever and invokes (*priv->so->so_upcall)(so, so->so_upcallarg, M_NOWAIT) out-of-band; 4,540,418 such foreign invocations were accepted in the hammer phase (flood_count, ksflood.c). The command is also exported in the public cmdlist. (2) HOWEVER the DF-0511-widening claim does not hold: both INTERNAL_UPCALL and NGM_SHUTDOWN are control messages and are dequeued strictly serially by the node's input queue, so an upcall flood cannot interleave with rmnode's so_upcall=NULL/soclose - 100 shutdown cycles under a 4.5M-send flood produced no panic and no anomaly. Net assessment: real missing-authorization (any hook-holding node can force out-of-band upcalls on the ksocket), no demonstrated memory-safety consequence on v1; hardening-grade.