DF-0315 / endpoint_crash_separate_bug.txt
SEPARATE BUG (NOT DF-0315) -- bonus observation during DF-0315 verification
=========================================================================
While trying to isolate the DF-0315 destroy-race UAF, a DIFFERENT, trivially
triggerable kernel panic was found in the WireGuard module. It is recorded
here so the orchestrator can file it as a separate finding. It is NOT the
DF-0315 use-after-free: it fires with NO peer destruction at all.
Trigger
-------
- wg0 interface created, address 10.66.0.1/24, UP
- one peer configured with an IPv4 ENDPOINT (e.g. 203.0.113.66:51820)
and allowed-ip 10.66.0.0/24
- a single local user sends UDP (~500 pkt/s) to 10.66.0.5:9, which the
connected route hands to wg_output()
- NO SIOCSWG peer destroy, NO private key needed (NOPRIV), NO groomer
./wgrace with: NOPRIV=1 NORACE=1 NSEND=1 NGROOM=0 SDELAY=2000
Result
------
Kernel panics in ~15-20 s, reproducible 4/4 runs.
Fatal trap 12: page fault while in kernel mode
cpuid = 0; lapic id = 0
fault virtual address = 0xfffffffffffffffc
fault code = supervisor read data, page not present
instruction pointer = 0x8:0xffffffff807cb0cf
stack pointer = 0x10:0xfffff80065ddea00
frame pointer = 0x10:0xfffff80065ddea80
current process = Idle <-- network/wg taskqueue thread
kernel: type 12 trap, code=0
CPU0 stopping CPUs: 0x00000002
stopped
Stopped at udp_send+0x2cf: movl 0x4(%r14),%eax
db>
Analysis
--------
current process = Idle => the fault is on a wg/network taskqueue thread,
not in the user sendto() syscall. The wg send task (wg_deliver_out ->
wg_send -> sosend -> udp_send, if_wg.c:1991/2026) is dereferencing a
corrupted pointer (r14 = 0xfffffffffffffff8, fault at +4 => -4). This
occurs whenever wg tries to transmit a handshake/data packet to a
configured peer endpoint under even light load. It is a separate DoS
in if_wg (or the UDP send path it exercises); it requires root to
configure the peer, but the crash itself is traffic-driven and trivial.
Why it is NOT DF-0315
---------------------
DF-0315 is a use-after-free of wg_peer caused by wg_peer_destroy() racing
the data plane. This panic happens with destroy entirely DISABLED
(NORACE=1), so no peer struct is ever freed and there is no UAF. It is a
distinct defect and should be filed separately.
Reproduction cost
-----------------
~15-20 s at 1 sender / 2 ms delay on the master DEV guest. Extremely low.