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

NULL mbuf deref/panic on m_devget failure in ngdwrite

Summary

ngdwrite (:589-591): m=m_devget(buffer,len,0,NULL) NO NULL check. m_devget returns NULL when len<=0 (while(len>0) never executes mfirst NULL) or alloc fail. Line 591 NG_SEND_DATA_ONLY(error,hook,m) passes NULL m. ng_send_data CHECK_DATA_MBUF derefs m->m_flags INVARIANTS panic. GENERIC peer rcvdata called NULL m panics mtod/m_pkthdr. Trigger: write(fd,buf,0) len==0 m_devget NULL -> instant panic. Also len=uio_resid :563 truncates size_t to int negative wraps. Fix: check m NULL + gate len>0.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-0666 Β· 8 files
FileTypeDescriptionSize
README.md readme PoC evidence pack overview 941 B ↓ raw
VERDICT.md verdict NOT REPRODUCED β€” cited file is dead code; netgraph7 rewrite has the fix 2.3 KB ↓ raw
build.sh build-script no source to build 208 B view raw
run.sh run-script prints cited bug + netgraph7 rewrite's guards 592 B view raw
env.txt environment host uname + conf/files grep + cited bug + netgraph7 fix 586 B view raw
fix.diff suggested-fix delete dead sys/netgraph/ng_device.c (git apply --check OK) 15.0 KB view raw
../fix_build_combined.log build-log Combined 41-finding kernel build (rc=0, -Werror clean) 5.6 MB ↓ download
../fix_build_summary.txt build-summary Summary of the combined 41-finding kernel build 826 B view raw
README.md readme PoC evidence pack overview
↓ download raw

DF-0666 β€” PoC evidence pack

Summary

  • File: sys/netgraph/ng_device.c:589-591
  • Claim: m = m_devget(buffer, len, 0, NULL) with no NULL check; NG_SEND_DATA_ONLY(error, hook, m) then derefs the possibly-NULL m. write(fd, buf, 0) β‡’ len==0 β‡’ m_devget returns NULL β‡’ instant panic.

Verdict

NOT REPRODUCED on this kernel β€” cited file is dead code (not in sys/conf/files). The active sys/netgraph7/ng_device.c:460-467 explicitly guards uio_resid==0 and NULL-checks the mbuf allocation. See VERDICT.md.

How to "reproduce" (the source-level analysis only)

No build or run is needed: the cited file is not compiled. run.sh re-prints the dead-code evidence.

Environment

See env.txt.

Fix

fix.diff deletes the dead sys/netgraph/ng_device.c (same as DF-0664/DF-0663). The netgraph7 rewrite already has the missing NULL check and len==0 gate, so patching the dead file buys nothing.

VERDICT.md verdict NOT REPRODUCED β€” cited file is dead code; netgraph7 rewrite has the fix
↓ download raw

DF-0666 β€” VERDICT

Verdict: NOT REPRODUCED on this kernel β€” cited file is DEAD CODE (not built)

The m_devget NULL-deref claim against sys/netgraph/ng_device.c:589-591 is real at the source level:

589:    m = m_devget(buffer, len, 0, NULL);
590:
591:    NG_SEND_DATA_ONLY(error, connection->active_hook, m);

There is no NULL check on m after m_devget. If len == 0, m_devget's while (len > 0) loop never executes and it returns the initial NULL mfirst. NG_SEND_DATA_ONLY then derefs m->m_flags (CHECK_DATA_MBUF macro) β†’ INVARIANTS panic, or in a non-INVARIANTS build a NULL deref in ng_send_data itself.

The len value at :563 is int len = uio->uio_resid; — a size_t→int truncation that can wrap a huge uio_resid to a negative int, although the surrounding :583 if (len > 0) gate prevents the negative case from reaching m_devget.

However, the cited file is not built by any standard kernel or module (verified identical to DF-0663/DF-0664):

$ grep "ng_device" sys/conf/files
netgraph7/ng_device.c       optional netgraph7_device

Only sys/netgraph7/ng_device.c is built. Its ngdwrite (sys/netgraph7/ng_device.c:452-472) is a complete rewrite that explicitly guards against exactly this bug:

460:    if (uio->uio_resid == 0)
461:        return (0);                       /* <-- gates len==0 */
...
466:    if ((m = m_uiotombuf(uio, M_NOWAIT, 0, 0, M_PKTHDR)) == NULL)
467:        return (ENOBUFS);                 /* <-- NULL check */

The rewritten version uses m_uiotombuf (not m_devget) and has both the len==0 early return and the NULL check that the dead original lacks.

Why the live kernel cannot trigger this

Verified on the running guest (#0 build): - nm /boot/kernel/kernel | grep -E "ngdwrite" β†’ no matches - ls /boot/kernel/ | grep ng_device β†’ no module file exists - kldstat β†’ no ng_device module loaded

The OLD sys/netgraph/ng_device.c is dead code retained for historical reference; netgraph7 superseded it. Same situation as DF-0663 and DF-0664.

Delete the dead file (preferred). The bundled fix.diff deletes sys/netgraph/ng_device.c. This supersedes the finding's source proposal (add NULL check + len gate) β€” the netgraph7 rewrite already has both, so patching the dead file buys nothing.

Fix verification

not_testable

n/a

see evidence pack

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

Dead code. Same file as DF-0663/0664. Netgraph7 rewrite already has the fix.