devfs_uninit passes NULL to devfs_msg_send β two stores through address 0 (latent; SYSUNINIT path dead on stock configs)
| Field | Value |
|---|---|
| ID | DF-3007 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:N |
| CWE | CWE-476 (write) |
| File | sys/vfs/devfs/devfs_core.c |
| Lines | 2751 β :1112-1119 (stores via msgport2.h:33-38) |
| Area | vfs/devfs |
| Confidence | certain |
| Discovered | 2026-09-02 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | memcorrupt |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
devfs_msg_send(DEVFS_TERMINATE_CORE, NULL) feeds NULL into lwkt_initmsg(&devfs_msg->hdr, ...) β hdr is at offset 0 of struct devfs_msg, so this writes ms_flags and ms_reply_port to address 0, then lwkt_sendmsg(port, NULL). Any execution is a guaranteed panic. None on current stock systems, empirically proven: DragonFly never executes the static sysuninit_set (mi_startup walks only sysinit_set; SYSUNINITs run only for KLD modules via linker_file_sysuninit) and builtin devfs cannot be unloaded β two clean shutdown -r cycles, zero panics. Filed as hardening: instantly fatal if devfs ever becomes unloadable or a sysuninit shutdown walker is introduced. Honest verdict: not_reproduced (path dead). Fix: allocate a real message (row diff).
Timeline
- 2026-09-02 Discovered during pass-2 audit of devfs_core.c (GLM 5.3).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3007 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.4 KB | β raw | |
| VERDICT.md | β | 2.4 KB | β raw | |
| run.log | β | 353 B | view raw | |
| env.txt | β | 280 B | view raw | |
| fix.diff | β | 550 B | view raw |
DF-3007 β devfs_uninit passes NULL to devfs_msg_send -> guaranteed NULL-pointer write (latent)
- File:
sys/vfs/devfs/devfs_core.c:2751(devfs_msg_send(DEVFS_TERMINATE_CORE, NULL)) sys/vfs/devfs/devfs_core.c:1112-1119(unconditional deref)sys/sys/msgport2.h:33-38(lwkt_initmsgstores throughmsg)- Class: CWE-476 NULL pointer dereference (write)
- Severity: Info β latent: unreachable on a stock system (see VERDICT)
Build / Run
No build. As root on the guest:
shutdown -r now # then inspect the serial console / boot log
Expected (had the path executed)
devfs_msg_send immediately executes lwkt_initmsg(&devfs_msg->hdr, ...)
with devfs_msg == NULL β hdr is the first member of struct devfs_msg
(sys/sys/devfs.h:165-166), so this is a write to address 0 -> kernel panic.
Observed
Two clean reboots, no panic, guest returns to login: β the SYSUNINIT entry
never executes on this configuration (static-kernel sysuninit_set has no
consumer on DragonFly; SYSUNINITs run only for KLD modules via
linker_file_sysuninit, sys/kern/kern_linker.c:535). Details and the
dead-path trace are in VERDICT.md. run.log holds the reboot attempt log.
Fix
fix.diff β allocate a real message (devfs_msg_get()); it is auto-freed
via devfs_dispose_port's devfs_msg_autofree_reply. Compile-validated in
the fix build.
DF-3007 VERDICT
Status: not_reproduced β the NULL-deref is real by construction but the code path is dead on a stock DragonFly system. Severity Info (latent).
The bug (certain, by code reading)
sys/vfs/devfs/devfs_core.c:2751:
devfs_msg_send(DEVFS_TERMINATE_CORE, NULL);
devfs_msg_send (devfs_core.c:1112-1119) unconditionally does:
lwkt_initmsg(&devfs_msg->hdr, &devfs_dispose_port, 0);
devfs_msg->hdr.u.ms_result = cmd;
struct devfs_msg begins with struct lwkt_msg hdr (sys/sys/devfs.h:165),
so &NULL->hdr == NULL, and lwkt_initmsg (sys/sys/msgport2.h:33-38)
writes msg->ms_flags and msg->ms_reply_port β i.e. two stores to
address 0, followed by lwkt_sendmsg(port, NULL). Any execution panics.
Runtime reachability β traced dead on this guest
devfs_uninitis registered bySYSUNINIT(vfs_devfs_register, SI_SUB_DEVFS_CORE, SI_ORDER_ANY, ...)atdevfs_core.c:2805-2806.- DragonFly's boot code (
sys/kern/init_main.c:200-270,mi_startup) walks onlysysinit_set; the staticsysuninit_sethas no consumer anywhere in the kernel β grep ofsys/kernfindssysuninitexecuted only inlinker_file_sysuninit(sys/kern/kern_linker.c:188-198,535), which is called fromlinker_file_unloadfor KLD modules only. - devfs is compiled into the stock kernel (
vfs.rootuses it; the devfs module cannot be unloaded β it owns /dev). Thereforedevfs_uninitnever runs on this system. - Empirical: two
shutdown -r nowcycles on the guest β no panic, clean reboot tologin:both times (run.log).
Classification per the honest table: "expected marker absent, run exits 0, guest stays up" -> not_reproduced, impact none. The finding is kept because the code is objectively broken and would fire instantly if anyone ever makes devfs unloadable or adds a sysuninit walker (FreeBSD-style shutdown runs SYSUNINITs; DF ports of that machinery would trip this).
Fix validation
Not applicable beyond compilation: the path cannot be executed on this
system (that is the finding itself). fix.diff was applied in the guest
/usr/src and compiled in the patched kernel build (build log /tmp/kbuild.log
in guest) β it compiles and changes no runtime behavior on stock configs.
Fix
- devfs_msg_send(DEVFS_TERMINATE_CORE, NULL);
+ msg = devfs_msg_get();
+ devfs_msg_send(DEVFS_TERMINATE_CORE, msg);
+ /* msg is auto-freed through the devfs_dispose_port reply */
Fix verification
not_testablefix.diff compiled cleanly in the patched kernel build; the runtime path is dead on stock configs by definition of the finding, so behavioral validation is not possible (not_testable).
guest /tmp/kbuild.log BUILD_OK with the patch applied
Confirmed kernel references
Detail
Evidence (decisive lines)
run.log (two clean reboots, no panic on serial console); VERDICT.md path trace: devfs_core.c:2751 -> devfs_core.c:1117 -> msgport2.h:33-38 stores through NULL; dead-path proof at init_main.c:200-270 + kern_linker.c:188-198,535.
PoC changes
None; trigger is simply a clean reboot with serial console watched live.
Verified recommended fix
Allocate a real message in devfs_uninit (msg = devfs_msg_get(); devfs_msg_send(DEVFS_TERMINATE_CORE, msg)) - auto-freed via devfs_dispose_port.
Verdict
Latent NULL-pointer write, provable by construction but unreachable on stock configurations: devfs_uninit (devfs_core.c:2751) passes NULL to devfs_msg_send, which unconditionally runs lwkt_initmsg(&devfs_msg->hdr,...) with hdr at offset 0 of struct devfs_msg - two stores to address 0 - followed by lwkt_sendmsg(port, NULL). Two clean shutdown -r cycles on the guest produced no panic because DragonFly never executes the static sysuninit_set (mi_startup walks only sysinit_set, init_main.c:200-270; sysuninit entries run solely for KLD modules via linker_file_sysuninit, kern_linker.c:535) and builtin devfs cannot be unloaded. Filed as Info/hardening: the code is dead-on-arrival for any future consumer (module-ized devfs or a FreeBSD-style shutdown sysuninit walker).
No comments yet.