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

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.

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2796 Β· 5 files
FileTypeDescriptionSize
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_testable
baseline reproduced→ patch + rebuild →patched clean

fix.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']
↓ fix.diffper-fix-DF-2796

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