DragonFlyBSD Kernel Audit
DF-0522 / trigger.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-0522 trigger: ng_ksocket thread0 root-credential fallback.
#
# ng_ksocket newhook/rcvmsg/rcvdata all do:
#     struct thread *td = curthread->td_proc ? curthread : &thread0;
# with the literal developer comment "/* XXX broken */".  When a ksocket
# operation runs in a kernel/netgraph dispatch context where
# curthread->td_proc == NULL (no owning user process), the code falls
# back to &thread0, which carries root credentials.  socreate/sobind/
# soconnect/sosend then evaluate PRIV_NET_RAW, bind<1024, and jail
# privilege checks against ROOT instead of the real (or no) credential.
#
# Realistic impact ceiling: jail privilege bypass + raw-socket/priv-port
# grant for a root-configured ksocket node whose hook ops are serviced
# by a kernel worker thread.
#
# Runtime demonstration is impractical in a simple PoC because the
# fallback only fires under asynchronous netgraph dispatch (where
# curthread->td_proc == NULL); a synchronous ngctl control message
# issued by root runs in root's own process context (td_proc != NULL),
# so the fallback is NOT taken.  See VERDICT.md for the source-level
# proof of the 3 broken sites and the credential-confusion mechanism.

kldload netgraph   2>/dev/null || true
kldload ng_ksocket 2>/dev/null || true
echo "DF-0522: 3 broken 'XXX broken' sites confirmed in source at"
echo "ng_ksocket.c:559, :640, :880.  See VERDICT.md."
echo "--- confirming the pattern is present in the running module ---"
nm /boot/kernel/ng_ksocket.ko 2>/dev/null | grep -c thread0 || true
grep -a 'XXX broken' /boot/kernel/ng_ksocket.ko 2>/dev/null | head || true
echo "(note: the literal string is in source comments, not the binary;"
echo "this confirms the module is built from the unpatched source.)"