⬢ DragonFlyBSD Kernel Audit
DF-3357 / verdict.json
← back to finding ↓ download raw
{
 "finding_id": "DF-3357",
 "status": "reproduced",
 "reproduced": 1,
 "impact": "leak",
 "confidence": "certain",
 "verdict": "REPRODUCED on DragonFly 6.5-DEVELOPMENT (stock INVARIANTS kernel #0): an unprivileged sendto() with a 2-byte destination sockaddr ({sa_len=2, sa_family=AF_INET}) on a UDP socket bound to a specific address makes udp_send() read sin_port/sin_addr (bytes 2..8) out of the 2-byte kmallocd M_SONAME chunk and emit a UDP packet whose destination address AND port are uninitialized/recycled kernel-heap bytes. Observed: 50/50 calls emitted packets to 255.255.255.255:65535 (0xFF filler of the recycled chunk), datagrams output +50; wildcard-bound control socket emitted +0 (validation gate isolated). The read stays inside the 8-byte slab chunk, so this is a heap info-leak-to-network (up to 6 bytes per packet, = another process stale sockaddr content on production kernels) plus traffic injection to unspecified destinations \u2014 not memory corruption. Fixed by validating sa_len/family before first use; fix validated by kernel rebuild (trigger +0 packets, normal sends unaffected).",
 "exploit_chain": "",
 "evidence": [
  "run.log: baseline control (+0) vs trigger (+50 datagrams output) and tcpdump capture IP 10.0.2.15.1494 > 255.255.255.255.65535: UDP, length 1 \u2014 destination never supplied by the 2-byte sendto",
  "run.4.log: control experiment isolating the udp_usrreq.c:1057 validation-skip gate",
  "VERDICT.md: root-cause walk udp_usrreq.c:1009-1048 -> in_pcb.c:954-959 (validation only at udp_usrreq.c:1071, conditional)",
  "fix_validation.log: baseline reproduced on kernel #0; after fix.diff kernel #1 the trigger emits 0 packets; normal 16-byte sendto still delivered (lo0 capture)"
 ],
 "kernel_refs": [
  "sys/netinet/udp_usrreq.c:1009",
  "sys/netinet/udp_usrreq.c:1046",
  "sys/netinet/udp_usrreq.c:1057",
  "sys/netinet/udp_usrreq.c:1071",
  "sys/netinet/in_pcb.c:954",
  "sys/kern/uipc_syscalls.c:1519",
  "sys/kern/kern_slaballoc.c:641"
 ],
 "poc_changes": "Seed PoC assumed groom-and-loopback receiver delivery; DFs slab allocator zone selection (TAILQ_LAST ZoneAry + z_LChunks) made groom-chunk reuse unreliable and loopback-source packets were martian-dropped off the egress interface. Final PoC instead binds the sender to the egress IP (10.0.2.15) so the heap-destined packets are emitted and captured on vtnet0, and adds a wildcard-bound control run isolating the validation-skip gate. Added missing <stdlib.h> include for exit().",
 "attempts": 7,
 "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": 2100,
 "guest_dirty": 1,
 "build_cmd": "cc -O -Wall -o udp_short_sockaddr udp_short_sockaddr.c",
 "run_cmd": "./udp_short_sockaddr w (control) && ./udp_short_sockaddr 10.0.2.15 (trigger) && tcpdump -i vtnet0 -n udp",
 "code_hash": "5f54d1d4c7a5a8362e553da52809d9857bfdf125adc2d2ef23e640bdadd4eeeb",
 "notes": "Impact ceiling: info-leak-to-network (packet destination field discloses up to 6 recycled-heap bytes; on production kernels that is stale M_SONAME content, i.e. other processes sockaddr_in destinations) + emission of packets to unintended destinations (observed limited broadcast). Not memory corruption (read stays within the 8-byte slab chunk). Related-but-distinct known findings not re-reported: DF-3304 (IP_MULTICAST_VIF no priv check, ip_output.c:1479), DF-0407 (IP_OPTIONS copyin error overwrite), DF-0409 (unpriv LSRR). udp6 twin (udp6_output.c) should be checked for the same pattern. Guest was reset to the clean with-src snapshot after validation.",
 "recommended_fix": "In udp_send(), validate the destination sockaddr (sin_len == sizeof(struct sockaddr_in), sin_family == AF_INET) immediately after the EISCONN check, before reading any field beyond sa_family (mirrors udp_bind:1460 / in_pcbladdr_find:954-957); see fix.diff.",
 "fix_status": "fixed",
 "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Fri Sep 11 08:24:42 UTC 2026   root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
 "fix_baseline_reproduced": 1,
 "fix_patched_reproduced": 0,
 "fix_verdict": "fix.diff applied to /usr/src in-guest, kernel rebuilt (make nativekernel, exit 0), installed and booted (kernel #1). Identical PoC: trigger emits 0 packets (was +50 on baseline); normal 16-byte-sockaddr sendto still delivered (lo0 tcpdump capture). Bad behavior gone, no regression.",
 "fix_evidence": "fix_validation.log"
}