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)
PoC verification
Evidence pack
findings/poc/DF-0666 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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 |
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-NULLm.write(fd, buf, 0)βlen==0βm_devgetreturns 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.
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.
Recommended fix
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_testablen/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.
No comments yet.