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

downstream_hook.dlci never initialized to -1: downstream traffic misrouted into the DLCI branch and reflected back out the downstream hook; decode/demux branch is dead code

Summary

struct XXX_hookinfo.downstream_hook is zeroed by the constructor's M_ZERO kmalloc and ng_xxx_newhook never sets downstream_hook.dlci = -1 (the value both the field comment and the data-path dispatch require). Every packet arriving on 'downstream' therefore takes the DLCI-egress branch and is forwarded back out downstream_hook.hook - the same hook it arrived on - instead of running the intended decode branch, which is unreachable. Counters wrong too (packets_out incremented where packets_in is meant). LIVE-VERIFIED on the guest with the ng7 stack loaded: 'PING' written into sample:downstream is read back verbatim on the sending socket; GET_STATUS reports packets_in=0/packets_out=1. Module builds from source (RC=0, live-verified) but does NOT ship (absent from Makefile SUBDIR, /boot/kernel).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3545 Β· 8 files
FileTypeDescriptionSize
sampledemo.c β€” 4.7 KB view raw
module-build.log β€” 1.1 KB view raw
run.log β€” 346 B view raw
env.txt β€” 426 B view raw
fix.diff β€” 428 B view raw
build.sh β€” 130 B view raw
run.sh β€” 189 B view raw
VERDICT.md β€” 2.5 KB ↓ raw
VERDICT.md
↓ download raw

DF-3545 β€” ng_sample (ng7) downstream hook misclassified as DLCI 0

Verdict: REPRODUCED (functional misroute/reflection; no memory-safety impact)

struct XXX_hookinfo downstream_hook is zeroed by the constructor's M_ZERO kmalloc (sys/netgraph7/ng_sample.c:158-165) and ng_xxx_newhook never sets downstream_hook.dlci = -1 (ng_sample.c:232-236), although both the struct comment (ng_sample.c:125: "-1 == downstream") and the data-path dispatch (ng_sample.c:341: if (dlci != -1)) require exactly that. Every packet arriving on the downstream hook therefore takes the DLCI-egress branch:

if (dlci != -1) {          /* 0 != -1 -> TRUE for downstream */
        NG_FWD_NEW_DATA(error, item, xxxp->downstream_hook.hook, m);
        xxxp->packets_out++;

(ng_sample.c:341-350) and is reflected straight back out the same hook it arrived on, instead of running the intended decode/demux branch (:351-376), which is unreachable dead code. Counters are also wrong (packets_out instead of packets_in).

Live confirmation on the guest (ng7 base + ng_socket + ng_sample modules built from /usr/src/sys/netgraph7 and loaded):

RESULT: REFLECTED - received 64 bytes back: 'PING\n'
GET_STATUS: packets_in=0 packets_out=1

sampledemo.c connects a data socket to sample:downstream, writes PING, and reads the same frame back on the same socket (run.log).

Impact ceiling: none beyond misrouting/reflection inside a graph an administrator explicitly built with this node. ng_sample is the netgraph template ("sample"/xxx node type): it builds (RC=0, module-build.log) and loads, but it does not ship β€” it is in no SUBDIR of sys/netgraph7/Makefile, has no sys/conf/files entry, and /boot/kernel contains no ng_sample.ko. Known finding DF-0690 (debug-hook mbuf+item leak) covers the other dormant-template defect in this file and is not re-reported here.

Fix

Set the sentinel in newhook (fix.diff). (Optionally also clear xxxp->debughook on debug-hook disconnect β€” noted in the audit as a latent-but-unused dangling pointer; debughook is never read, so it is recorded as a negative note rather than a finding.)

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
baseline reproduced→ patch + rebuild →patched clean

One-line sentinel fix (downstream_hook.dlci = -1 in newhook); kernel rebuild validation skipped per contract for Info-severity findings.

fix.diff
↓ fix.diffper-fix-DF-3545

Confirmed kernel references

Detail

Evidence (decisive lines)

run.log (RESULT: REFLECTED + packets_in=0/packets_out=1), sampledemo.c, module-build.log (build RC=0 + shipping status), VERDICT.md

PoC changes

Demo written from scratch; required the ng7 ng_mesg layout (arglen u32 @4, cmd @8, flags @12, token @16, typecookie @20, data @56) and ng7 NGM_GENERIC_COOKIE 1137070366 / NG_VERSION 8 - the system ngctl/nghook are compiled against the v1 ABI and cannot drive the ng7 stack.

Verified recommended fix

Set xxxp->downstream_hook.dlci = -1 when accepting the downstream hook in ng_xxx_newhook (ng_sample.c:232).

Verdict

Reproduced live on the ng7 stack: a frame written into sample:downstream is reflected straight back out the same hook (readable again on the sending socket) and GET_STATUS reports packets_in=0/packets_out=1, because downstream_hook.dlci stays 0 (constructor M_ZERO at sys/netgraph7/ng_sample.c:158-165; newhook at :232-236 never sets -1) so rcvdata's 'dlci != -1' DLCI branch at :341 runs and forwards back out downstream_hook.hook at :348; the intended decode branch (:351-376) is unreachable. Module builds (RC=0) and loads, but does not ship (no SUBDIR entry, no sys/conf/files line, absent from /boot/kernel). Dormant template - misroute/reflection only, administrator must explicitly instantiate the node. DF-0690 (debug-hook leak) not re-reported.