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<NUM_PEER; i++)); do port="$RANDOM" private="$(wg genkey)" ifconfig "wg$i" create wg set "wg$i" listen-port "$port" private-key <(echo "$private") peer_args+=( peer "$(wg pubkey <<<"$private")" endpoint "127.0.0.1:$port" persistent-keepalive 1 ) done for ((i=0; i<NUM_PEER; i++)); do wg set "wg$i" "${peer_args[@]}" ifconfig "wg$i" up done wg while true; do for ((i=0; i<NUM_PEER; i++)); do ifconfig "wg$i" down ifconfig "wg$i" up done done Reported-by: Manojav Sridhar <manojav@manojav.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
280bee380d
commit
561f3a8f93
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue