diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2017-06-06 21:49:29 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2017-06-08 04:24:13 +0200 |
commit | f2ce3e868c91cb84819eb89019484301feffe87d (patch) | |
tree | d3562e7233346f1904ec58ae9bc7292f11b13d79 /src/hashtables.c | |
parent | d93bc3aa7ee43f11786432148f3ac81f594790ec (diff) |
noise: fix race when replacing handshake
Replacing an entry that's already been replaced is something that could
happen when processing handshake messages in parallel, when starting up
multiple instances on the same machine.
Reported-by: Hubert Goisern <zweizweizwoelf@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/hashtables.c')
-rw-r--r-- | src/hashtables.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/src/hashtables.c b/src/hashtables.c index db97f7e..a01a899 100644 --- a/src/hashtables.c +++ b/src/hashtables.c @@ -97,13 +97,16 @@ search_unused_slot: return entry->index; } -void index_hashtable_replace(struct index_hashtable *table, struct index_hashtable_entry *old, struct index_hashtable_entry *new) +bool index_hashtable_replace(struct index_hashtable *table, struct index_hashtable_entry *old, struct index_hashtable_entry *new) { + if (unlikely(hlist_unhashed(&old->index_hash))) + return false; spin_lock_bh(&table->lock); new->index = old->index; hlist_replace_rcu(&old->index_hash, &new->index_hash); INIT_HLIST_NODE(&old->index_hash); spin_unlock_bh(&table->lock); + return true; } void index_hashtable_remove(struct index_hashtable *table, struct index_hashtable_entry *entry) |