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

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3007 Β· 5 files
FileTypeDescriptionSize
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)

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.

VERDICT.md
↓ download raw

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

  1. devfs_uninit is registered by SYSUNINIT(vfs_devfs_register, SI_SUB_DEVFS_CORE, SI_ORDER_ANY, ...) at devfs_core.c:2805-2806.
  2. DragonFly's boot code (sys/kern/init_main.c:200-270, mi_startup) walks only sysinit_set; the static sysuninit_set has no consumer anywhere in the kernel β€” grep of sys/kern finds sysuninit executed only in linker_file_sysuninit (sys/kern/kern_linker.c:188-198,535), which is called from linker_file_unload for KLD modules only.
  3. devfs is compiled into the stock kernel (vfs.root uses it; the devfs module cannot be unloaded β€” it owns /dev). Therefore devfs_uninit never runs on this system.
  4. Empirical: two shutdown -r now cycles on the guest β€” no panic, clean reboot to login: 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_testable
baseline no→ patch + rebuild →patched clean

fix.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
↓ fix.diffDragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Sat Sep 5 04:09:39 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64

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).