diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-08-01 15:59:37 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-08-03 00:14:18 +0200 |
commit | 9f4cc375561f34a6512f3789edbbd3d7a900145f (patch) | |
tree | 06c28c1a36d2b03c79fa6bbffb1a39cd49858dac /src/hashtables.c | |
parent | 7dbb9eec2638b41a0b95f3ca196d3c3a8550173c (diff) |
peer: ensure destruction doesn't race
Completely rework peer removal to ensure peers don't jump between
contexts and create races.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/hashtables.c')
-rw-r--r-- | src/hashtables.c | 6 |
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(); |