From 561f3a8f930cf2e44f493fa04d932ba9a2362cc5 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 3 May 2021 16:31:25 +0200 Subject: wg_noise: set handshake to dead before removing keypair Otherwise CK_LIST_REMOVE might be called twice on the same element. Running the following trigger will reproduce the bug that Manojav reported: #!/usr/local/bin/bash NUM_PEER=50 peer_args=( ) for ((i=0; i Signed-off-by: Jason A. Donenfeld --- src/wg_noise.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wg_noise.c b/src/wg_noise.c index cb9f525..41f7f50 100644 --- a/src/wg_noise.c +++ b/src/wg_noise.c @@ -445,9 +445,9 @@ noise_remote_index_remove(struct noise_local *l, struct noise_remote *r) rw_assert(&r->r_handshake_lock, RA_WLOCKED); if (r->r_handshake_state != HANDSHAKE_DEAD) { rw_wlock(&l->l_index_lock); + r->r_handshake_state = HANDSHAKE_DEAD; CK_LIST_REMOVE(&r->r_index, i_entry); rw_wunlock(&l->l_index_lock); - r->r_handshake_state = HANDSHAKE_DEAD; return (1); } return (0); @@ -634,6 +634,7 @@ noise_add_new_keypair(struct noise_local *l, struct noise_remote *r, rw_wlock(&l->l_index_lock); CK_LIST_INSERT_BEFORE(r_i, &kp->kp_index, i_entry); + r->r_handshake_state = HANDSHAKE_DEAD; CK_LIST_REMOVE(r_i, i_entry); rw_wunlock(&l->l_index_lock); @@ -1346,7 +1347,7 @@ noise_tai64n_now(uint8_t output[NOISE_TIMESTAMP_LEN]) memcpy(output + sizeof(sec), &nsec, sizeof(nsec)); } -static __inline int +static inline int noise_timer_expired(sbintime_t timer, uint32_t sec, uint32_t nsec) { sbintime_t now = getsbinuptime(); -- cgit v1.2.3-59-g8ed1b