DragonFlyBSD Kernel Audit
DF-2702 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-2702",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "leak",
  "confidence": "certain",
  "verdict": "recvmsg(MSG_PEEK) on an AF_UNIX socket with a queued SCM_RIGHTS message copies the control mbuf (m_copym) without running dom_externalize/unp_externalize, disclosing raw kernel struct file pointers to unprivileged users. Reproduced as uid=1001 on SOCK_STREAM (controllen=32=CMSG_LEN(2*8), slots 0xfffff801167ffd80/0xfffff801167ffe80, stable across peeks) and SOCK_DGRAM (0xfffff801167e5500), 4/4 runs kernel-range; real recvmsg of the same message externalizes to fds 6,7, proving the peek branch is the anomaly. Root cause uipc_socket.c:1422-1425 interacting with unp_internalize (uipc_usrreq.c:1817-1825) and unp_externalize (uipc_usrreq.c:1543). fix.diff validated on an in-guest nativekernel build (#1): peek returns controllen=0 for rights (leak gone), SCM_CREDS peek intact, real fd passing intact.",
  "exploit_chain": "",
  "evidence": [
    "run.log: PEEK controllen=32, cmsg_len=32, slots 0xfffff801167ffd80 and 0xfffff801167ffe80 marked 'RAW KERNEL POINTER', identical across PEEK #0/#1; REAL RECV controllen=24 with fds 6,7",
    "run.2.log: SOCK_DGRAM variant leaks 0xfffff801167e5500; fresh-process rerun leaks new pointers 0xfffff801167e5e80/... (4/4 kernel-range)",
    "fix_validation.log: patched kernel #1 PEEK controllen=0 (no pointers), REAL recv controllen=24 fds 6,7; creds_peek: SCM_CREDS still peekable (controllen=104, type=3)",
    "fix.diff: MSG_PEEK branch skips returning unreplaced SCM_RIGHTS control",
    "VERDICT.md: full narrative + negative-space analysis of uipc_usrreq.c"
  ],
  "kernel_refs": [
    "sys/kern/uipc_socket.c:1421-1425",
    "sys/kern/uipc_usrreq.c:1543-1633",
    "sys/kern/uipc_usrreq.c:1817-1825",
    "sys/kern/uipc_usrreq.c:636-637",
    "sys/kern/uipc_syscalls.c:1172-1189",
    "sys/kern/uipc_syscalls.c:934-943"
  ],
  "poc_changes": "PoC authored fresh (no seed). Two-peek + real-recv design to prove internalized-vs-externalized cmsg_len delta (32 vs 24) and pointer stability; added SOCK_DGRAM and SCM_CREDS-post-fix variants.",
  "attempts": 3,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "runtime_sec": 210,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -o peek_rights_leak peek_rights_leak.c",
  "run_cmd": "./peek_rights_leak  (uid=1001; plus ./dgram_peek)",
  "code_hash": "7425fae3407f8a82269aa12cefef09d738bc222a354d2256a0aa0d7248c0b0ff",
  "notes": "Info leak, not memory corruption - no uid0 chain applicable; impact is defeat of heap-address randomization and reliable slab targeting for separate corruption bugs. uipc_usrreq.c itself audited clean beyond known findings (see VERDICT.md negative space: sa_len normalized by getsockaddr, xunpcb 256B unions, single-mbuf control chains, fp-ref protects unpcb across blocking token release, balanced unp_reference/unp_free, unp_gc overcount benign).",
  "recommended_fix": "soreceive MSG_PEEK branch: do not return unreplaced SCM_RIGHTS control to userland (skip rights cmsgs on peek; externalize only on consume)",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Mon Aug 31 02:02:55 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Patched kernel #1 (make nativekernel with fix.diff): PEEK returns controllen=0 for SCM_RIGHTS (baseline pointers 0xfffff801xxxxxxxx gone); SCM_CREDS peek still returns control (controllen=104, type=3); real recvmsg still externalizes fds correctly (controllen=24, fds 6,7). Bad behavior eliminated, no functional regression.",
  "fix_evidence": [
    "fix_validation.log",
    "fix_build_excerpt.txt",
    "fix.diff"
  ]
}