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
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 msgaddress in theM_MSGslab) 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).
Recommended fix
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
sys/kern/sysv_msg.c:324โ verbatim IPC_STAT copyout.sys/sys/msg.h:70-71,78-83โmsg_first/msg_last/msg_pad*.- CWE-200; CWE-909.
Timeline
- 2026-06-29 Discovered during automated file-by-file audit of
sys/kern/sysv_msg.c. - pending Reported to DragonFlyBSD security contact.