linux/drivers/net/wireguard
Jason A. Donenfeld d0305f8d90 wireguard: noise: reject response consumption after intermediate initiation
Two threads begin processing the identical response message, received
twice. The first thread, A, runs. While it's running, the second one,
B, gets partway through, and during that slow calculation, or even while
blocking on down_write(), A completes and then also a handshake
initiation that's already been queued up runs in thread C, which itself
takes that same down_write(). The handshake initiation creation
succeeds, and sets the state back to waiting-for-response, and calls
up_write(), at which point thread B resumes, because either its finished
its calculations or was finally allowed to acquire down_write(). Thread
B then copies the state back to the peer, and begins a new session,
using that state, which is the same session as the one made in thread A.

Thread A			Thread B			Thread C

down_read()
 sA = handshake->state
 memcpy(cA, handshake->crypto)
up_read()
if (sA != 1)
 goto fail
slow_crypto(cA)
				down_read()
				 sB = handshake->state
				 memcpy(cB, handshake->crypto)
				up_read()
				if (sB != 1)
				 goto fail
				slow_crypto(cB)
down_write()
 if (sA != handshake->state)
  goto fail
 memcpy(handshake->crypto, cA)
 handshake->state = 2
up_write()
down_write()
 if (handshake->state != 2)
  goto fail
 derive_session(handshake->crypto)
up_write()
								down_write()
								 slow_crypto(handshake->crypto)
								 handshake->state = 1
								up_write()
				down_write()
				 if (sB != handshake->state)
				   goto fail
				 memcpy(handshake->crypto, cB)
				 handshake->state = 2
				up_write()
				down_write()
				 if (handshake->state != 2)
				  goto fail
				 derive_session(handshake->crypto)
				up_write()

This seems basically impossible to hit in a meaningful way in practice,
but ensure that it absolutely cannot happen by comparing the ephemeral
private key that's on the stack with the latest one that the peer's
handshake state has.

Cc: stable@vger.kernel.org
Fixes: e7096c131e ("net: WireGuard secure network tunnel")
Reported-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Link: https://patch.msgid.link/20261008130124.724119-4-Jason@zx2c4.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-08 11:43:38 -07:00
..
generated wireguard: netlink: generate netlink code 2025-12-02 04:12:49 +01:00
selftest wireguard: allowedips: remove redundant space 2026-04-14 11:48:04 -07:00
allowedips.c wireguard: allowedips: Use kfree_rcu() instead of call_rcu() 2026-04-14 11:48:04 -07:00
allowedips.h wireguard: allowedips: add WGALLOWEDIP_F_REMOVE_ME flag 2025-05-27 09:06:19 +02:00
cookie.c lib/crypto: blake2s: Rename blake2s_state to blake2s_ctx 2025-10-29 22:04:24 -07:00
cookie.h
device.c wireguard: device: use exit_rtnl callback instead of manual rtnl_lock in pre_exit 2026-04-14 11:48:04 -07:00
device.h
main.c
Makefile wireguard: netlink: generate netlink code 2025-12-02 04:12:49 +01:00
messages.h
netlink.c wireguard: netlink: generate netlink code 2025-12-02 04:12:49 +01:00
netlink.h
noise.c wireguard: noise: reject response consumption after intermediate initiation 2026-10-08 11:43:38 -07:00
noise.h
peer.c
peer.h wireguard: peer: Replace sockaddr with sockaddr_inet 2025-07-25 15:29:58 -07:00
peerlookup.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
peerlookup.h
queueing.c
queueing.h wireguard: queueing: preserve tstamp_type when encapsulating packet 2026-10-08 11:43:38 -07:00
ratelimiter.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ratelimiter.h
receive.c net: Use helpers to get/set UDP len tree-wide 2026-07-22 13:47:02 +02:00
send.c wireguard: send: append trailer after expanding head 2026-05-29 13:01:27 -07:00
socket.c udp_tunnel: Pass struct sock to setup_udp_tunnel_sock(). 2026-05-05 17:47:04 -07:00
socket.h
timers.c treewide, timers: Rename from_timer() to timer_container_of() 2025-06-08 09:07:37 +02:00
timers.h
version.h