World-readable sysctl kern.ipc.msqids dumps raw kernel msqid_ds array: live kernel heap pointers and other users' queue metadata without any permission check
| Field | Value |
|---|---|
| ID | DF-2796 |
| 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 |
| File | sys/kern/sysv_msg.c |
| Lines | 1072-1077 (node :1095-1096) |
| Area | kern |
| Confidence | certain |
| Discovered | 2026-08-31 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | kernleak |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
sysctl_msqids SYSCTL_OUTs the live msqids[] array behind a plain CTLFLAG_RD sysctl. Every struct msqid_ds embeds msg_first/msg_last β live struct msg * pointers into the boot-time M_MSG msghdrs kmalloc β plus msg_pad1..4 the kernel never writes. Verified as uid 1001: sysctlbyname returned 6400 bytes; parser read msg_first=msg_last=0xfffff8008e0ea980 (stable across 3 runs). Same unsanitized-export root cause as DF-0050 but a distinct sink requiring no queue id and no IPC_R permission; additionally exposes every user's queue keys/owners/byte-counts. KASLR/heap-layout defeat enabler.
Proof of contest
VERIFIED on the stock guest (findings/poc/DF-2796/msqids_leak.c): canonical 0xfffff8β¦ pointers, stable across runs. Fix (export a sanitized snapshot β zero pointers/pads per slot; share the helper with the DF-0050 IPC_STAT fix) in the pack.
Recommended fix
See findings/poc/DF-2796/fix.diff.
Timeline
- 2026-08-31 Discovered during pass-2 audit of sysv_msg.c (GLM 5.3); unpriv leak reproduced same run.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2796 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| msqids_leak.c | β | 3.8 KB | view raw | |
| build.log | β | 5 B | view raw | |
| run.log | β | 473 B | view raw | |
| fix.diff | β | 966 B | view raw | |
| env.txt | β | 239 B | view raw |
Fix verification
not_testablefix.diff authored against read-only sys/ (sanitize snapshot before SYSCTL_OUT); not built/booted -- Low-severity leak whose fix is mechanical and shares its helper with the DF-0050 remediation.
['fix.diff']
Confirmed kernel references
Detail
Exploit chain
unpriv user: sysctlbyname("kern.ipc.msqids") -> parse slot of interest -> read msg_first/msg_last kernel heap pointer (KASLR/heap-layout defeat enabler) + other users' keys/owners/cbytes.
Evidence (decisive lines)
["run.log: 'kern.ipc.msqids readable by uid 1001: 6400 bytes', 'msg_first = 0xfffff8008e0eaa88', LEAK line, EXIT=0", 'VERDICT.md: three stable-pointer runs recorded (0xfffff8008e0ea980 x3, then 0xfffff8008e0eaa88 on fresh queue)', 'build.log: clean compile RC=0']
PoC changes
Replaced the seed's numeric mib (KERN_IPC_MSQIDS is not exported to userland headers) with sysctlbyname("kern.ipc.msqids"); explicit kernel-layout mirror struct so offsets are unambiguous.
Verified recommended fix
sysctl_msqids: export a zeroed-snapshot copy with msg_first/msg_last and pad fields cleared (see fix.diff).
Verdict
sysctl_msqids (sysv_msg.c:1072-1077) SYSCTL_OUTs the live kernel msqids[] array behind a world-readable sysctl (sysv_msg.c:1095-1096): any local user, with no queue id and no IPC_R permission, dumps all 40 msqid_ds structs including live kernel heap pointers msg_first/msg_last (into the boot-time M_MSG msghdrs allocation) and never-written padding. Demonstrated as uid 1001: sysctlbyname(kern.ipc.msqids) returned 6400 bytes and the parser read msg_first=msg_last=0xfffff8008e0ea980 (stable across 3 runs; 0xfffff8008e0eaa88 with a fresh queue). Distinct sink from DF-0050 (IPC_STAT copyout) sharing the same unsanitized-export root cause; the sysctl vector additionally exposes every other user's queue key/metadata. Low severity (pointer/layout disclosure; no KASLR on stock guest), fix.diff sanitizes a snapshot copy -- authored but not kernel-built (mechanical change, shares helper with DF-0050 fix).
No comments yet.