aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/hashtables.c
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-08-01 15:59:37 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2018-08-03 00:14:18 +0200
commit81eb0e30f9b39e99d1bb7b56828fd32e50ea055a (patch)
tree7b9e212d2a73644bae8b09da164147a4491d98fa /src/hashtables.c
parentnoise: free peer references on failure (diff)
downloadwireguard-monolithic-historical-81eb0e30f9b39e99d1bb7b56828fd32e50ea055a.tar.xz
wireguard-monolithic-historical-81eb0e30f9b39e99d1bb7b56828fd32e50ea055a.zip
peer: ensure destruction doesn't race
Completely rework peer removal to ensure peers don't jump between contexts and create races.
Diffstat (limited to 'src/hashtables.c')
-rw-r--r--src/hashtables.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/hashtables.c b/src/hashtables.c
index 03b9e21..ac6df59 100644
--- a/src/hashtables.c
+++ b/src/hashtables.c
@@ -152,7 +152,7 @@ void index_hashtable_remove(struct index_hashtable *table, struct index_hashtabl
}
/* Returns a strong reference to a entry->peer */
-struct index_hashtable_entry *index_hashtable_lookup(struct index_hashtable *table, const enum index_hashtable_type type_mask, const __le32 index)
+struct index_hashtable_entry *index_hashtable_lookup(struct index_hashtable *table, const enum index_hashtable_type type_mask, const __le32 index, struct wireguard_peer **peer)
{
struct index_hashtable_entry *iter_entry, *entry = NULL;
@@ -166,7 +166,9 @@ struct index_hashtable_entry *index_hashtable_lookup(struct index_hashtable *tab
}
if (likely(entry)) {
entry->peer = peer_get_maybe_zero(entry->peer);
- if (unlikely(!entry->peer))
+ if (likely(entry->peer))
+ *peer = entry->peer;
+ else
entry = NULL;
}
rcu_read_unlock_bh();