โฌข DragonFlyBSD Kernel Audit
โ† dashboard
DF-0050

msgctl(IPC_STAT) leaks kernel heap pointers (msg_first/msg_last) and uninitialized padding to any local user

Field Value
ID DF-0050
Status new
Severity Low
CVSS 3.1 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
CWE CWE-200 Exposure of Sensitive Information; CWE-909 Missing Initialization of Resource
File sys/kern/sysv_msg.c
Lines 324 (IPC_STAT copyout); struct in sys/sys/msg.h:68-84
Area kern
Confidence certain
Discovered 2026-06-29
Reported pending

Summary

sys_msgctl(IPC_STAT) does copyout(msqptr, user_msqptr, sizeof(struct msqid_ds)) with no field sanitization. struct msqid_ds (sys/sys/msg.h) contains struct msg *msg_first (:70) and *msg_last (:71) โ€” populated kernel heap pointers โ€” plus msg_pad1..msg_pad4 (:78,:80,:82,:83) that are never zeroed (the boot-time msqids kmalloc at sysv_msg.c:130 omits M_ZERO). Any local user who creates a queue (msgget(IPC_PRIVATE)) and sends one message can read the kernel address of the msg header (and possibly early-boot heap residue in the pad fields), defeating kernel heap ASLR / KASLR and aiding exploitation of a separate memory-corruption bug.

Root cause

sys/kern/sysv_msg.c:324:

eval = copyout(msqptr, user_msqptr, sizeof(struct msqid_ds));   /* verbatim */

msg_first/msg_last are assigned at msgsnd enqueue (:762-768) / msgget init (:427-428); the pad fields are never written.

Threat model & preconditions

  • Attacker position: any local unprivileged user.
  • Privileges gained or impact: information disclosure โ€” a live kernel heap pointer (the struct msg address in the M_MSG slab) plus possible boot-time heap residue. A reliable KASLR / heap-ASLR bypass that converts a separate unreliable kernel memory-corruption bug into a reliable exploit. No direct code execution.
  • Required config or capabilities: none; default kernel.
  • Reachability: msgget(IPC_PRIVATE) + msgsnd + msgctl(IPC_STAT).

Proof of concept

PoC source: findings/poc/DF-0050/msg_leak.c

Build & run (unprivileged)

cc -o msg_leak findings/poc/DF-0050/msg_leak.c
./msg_leak

Expected output

Kernel heap addresses for msg_first/msg_last.

Impact

Unprivileged kernel-heap-pointer disclosure (KASLR/heap-ASLR bypass / exploit enabler). Same class as DF-0006/DF-0009/DF-0016/DF-0025. Rated Low (info-leak).

Sanitize the pointer/pad fields in a local copy before copyout:

--- a/sys/kern/sysv_msg.c
+++ b/sys/kern/sysv_msg.c
@@ -321,7 +321,17 @@
        }
-       eval = copyout(msqptr, user_msqptr, sizeof(struct msqid_ds));
+       {
+           struct msqid_ds msqout = *msqptr;
+           msqout.msg_first = NULL;
+           msqout.msg_last = NULL;
+           msqout.msg_pad1 = 0;
+           msqout.msg_pad2 = 0;
+           msqout.msg_pad3 = 0;
+           bzero(msqout.msg_pad4, sizeof(msqout.msg_pad4));
+           eval = copyout(&msqout, user_msqptr, sizeof(msqout));
+       }

References

Timeline

  • 2026-06-29 Discovered during automated file-by-file audit of sys/kern/sysv_msg.c.
  • pending Reported to DragonFlyBSD security contact.