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

Kernel-internal MSG_FNONBLOCKING/MSG_FBLOCKING state leaks into user-visible msg_flags on every recvmsg(2) from a non-blocking socket

Field Value
ID DF-2715
Status new
Severity Info
CVSS 3.1 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:N
CWE CWE-200 (API semantics)
File sys/kern/uipc_syscalls.c
Lines 996-1005, 1195-1196
Area kern
Confidence certain
Discovered 2026-08-30
Pass 2 (GLM 5.3 second pass)
Bucket base:kern
Reported pending
Known CVE none
CVE match novel

Summary

kern_recvmsg() ORs MSG_FNONBLOCKING (0x20000) into *flags derived from the file's FNONBLOCK state, and sys_recvmsg() copies that flags word back into the user msghdr.msg_flags without masking the internal bits. Every recvmsg on an O_NONBLOCK socket reports msg_flags |= 0x20000. Semantics/API defect only (kernel fd state surfacing through a POSIX field userland uses for MSG_EOR/TRUNC/CTRUNC); no memory-safety impact.

Mask internal flags before the msg_flags copyout: flags &= ~(MSG_FNONBLOCKING|MSG_FBLOCKING); before the copyout at :1195.

Timeline

  • 2026-08-30 Discovered during pass-2 audit of uipc_syscalls.c (GLM 5.3).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2715 Β· 10 files
FileTypeDescriptionSize
VERDICT.md β€” 1.6 KB ↓ raw
README.md β€” 280 B ↓ raw
build.sh β€” 90 B view raw
run.sh β€” 96 B view raw
env.txt β€” 314 B view raw
manifest.json β€” 722 B view raw
verdict.json β€” 2.2 KB view raw
fix.diff β€” 504 B view raw
msgflags_leak.c β€” 1.8 KB view raw
run.log β€” 317 B view raw

DF-2715 evidence pack

  • finding: sys/kern/uipc_syscalls.c (996-1001 (force-flag OR), 1190 (copyout))
  • verdict: reproduced (certain) - see VERDICT.md
  • runtime PoC: msgflags_leak.c
  • reproduce: build.sh / run.sh ; expected output in run.log
  • fix.diff: present, git-apply-able
VERDICT.md
↓ download raw

DF-2715 - Verification Verdict

Status: reproduced Impact: leak Confidence: certain

Mechanism

kern_recvmsg ORs the kernel-internal force flags MSG_FNONBLOCKING/MSG_FBLOCKING (0x20000/0x10000, sys/socket.h:398-399) into its flags variable when the file is non-blocking; sys_recvmsg then copyout()s that same variable over the user msghdr.msg_flags with nothing stripping the kernel-only bits.

Verdict

REPRODUCED unprivileged on the stock guest: recvmsg on an O_NONBLOCK UDP socket with a queued datagram returns msg_flags = 0x00020000 - the kernel-internal MSG_FNONBLOCKING bit is visible in the user msghdr (twice, deterministic). POSIX defines msg_flags as an output field carrying MSG_TRUNC/MSG_CTRUNC/MSG_EOR-class status; two bits of kernel-internal state (which blocking mode the kernel forced) leak into every such recvmsg.

Threat / reachability

ABI/state disclosure to any local user; also a compatibility hazard (apps keying unknown msg_flags bits).

Privilege escalation assessment

n/a (info leak of kernel state bit)

Fix

Strip MSG_FNONBLOCKING|MSG_FBLOCKING from *flags after so_pru_soreceive returns.

Kernel references

Fix status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

Fix verification

not_testable

fix.diff compile-validated in the batch combined kernel build (all 37 diffs of this batch applied to in-guest /usr/src; make -j6 nativekernel KERNCONF=X86_64_GENERIC, see batch build log referenced in VERDICT.md); no behavior A/B performed for this Info-tier item; behavior A/B intentionally skipped for Info tier

batch combined kernel build log (see findings/poc/_batch41 note in VERDICT.md)
↓ fix.diffper-fix-DF-2715

Confirmed kernel references

Detail

Exploit chain

no escalation path: disclosure of one kernel state bit to the receiving process itself

Evidence (decisive lines)

run.log (two consecutive runs): recvmsg on O_NONBLOCK socket with data queued -> msg_flags = 0x00020000 (MSG_FNONBLOCKING leaked)

PoC changes

Initial version polled an empty socket: msg_flags is only copied out when recvmsg returns without error; added a self-sent datagram so the non-blocking receive succeeds and the flags word is written back.

Verified recommended fix

Strip MSG_FNONBLOCKING|MSG_FBLOCKING from *flags after so_pru_soreceive returns.

Verdict

REPRODUCED unprivileged on the stock guest: recvmsg on an O_NONBLOCK UDP socket with a queued datagram returns msg_flags = 0x00020000 - the kernel-internal MSG_FNONBLOCKING bit is visible in the user msghdr (twice, deterministic). POSIX defines msg_flags as an output field carrying MSG_TRUNC/MSG_CTRUNC/MSG_EOR-class status; two bits of kernel-internal state (which blocking mode the kernel forced) leak into every such recvmsg.