diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-08-01 03:53:09 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-08-01 05:53:31 +0200 |
commit | 97919beadae1fd9f4b2769233cd6704a1a520450 (patch) | |
tree | 8fc60974b039da350dd9530df6be9d306200acac /src/noise.c | |
parent | 9afa21904205a155ad6440896c409bd2c731e1e5 (diff) |
allowedips: prevent double read in kref
Blocks like:
if (node_placement(*trie, key, cidr, bits, &node, lock)) {
node->peer = peer;
return 0;
}
May result in a double read when adjusting the refcount, in the highly
unlikely case of LTO and an overly smart compiler.
While we're at it, replace rcu_assign_pointer(X, NULL); with
RCU_INIT_POINTER.
Reported-by: Jann Horn <jann@thejh.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/noise.c')
-rw-r--r-- | src/noise.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/src/noise.c b/src/noise.c index 1a28b47..c7a55e0 100644 --- a/src/noise.c +++ b/src/noise.c @@ -138,13 +138,13 @@ void noise_keypairs_clear(struct noise_keypairs *keypairs) spin_lock_bh(&keypairs->keypair_update_lock); old = rcu_dereference_protected(keypairs->previous_keypair, lockdep_is_held(&keypairs->keypair_update_lock)); - rcu_assign_pointer(keypairs->previous_keypair, NULL); + RCU_INIT_POINTER(keypairs->previous_keypair, NULL); noise_keypair_put(old); old = rcu_dereference_protected(keypairs->next_keypair, lockdep_is_held(&keypairs->keypair_update_lock)); - rcu_assign_pointer(keypairs->next_keypair, NULL); + RCU_INIT_POINTER(keypairs->next_keypair, NULL); noise_keypair_put(old); old = rcu_dereference_protected(keypairs->current_keypair, lockdep_is_held(&keypairs->keypair_update_lock)); - rcu_assign_pointer(keypairs->current_keypair, NULL); + RCU_INIT_POINTER(keypairs->current_keypair, NULL); noise_keypair_put(old); spin_unlock_bh(&keypairs->keypair_update_lock); } @@ -169,7 +169,7 @@ static void add_new_keypair(struct noise_keypairs *keypairs, struct noise_keypai * next keypair instead of putting it in the previous slot, but this * might be a bit less robust. Something to think about and decide on. */ - rcu_assign_pointer(keypairs->next_keypair, NULL); + RCU_INIT_POINTER(keypairs->next_keypair, NULL); rcu_assign_pointer(keypairs->previous_keypair, next_keypair); noise_keypair_put(current_keypair); } else /* If there wasn't an existing next keypair, we replace the @@ -189,7 +189,7 @@ static void add_new_keypair(struct noise_keypairs *keypairs, struct noise_keypai */ rcu_assign_pointer(keypairs->next_keypair, new_keypair); noise_keypair_put(next_keypair); - rcu_assign_pointer(keypairs->previous_keypair, NULL); + RCU_INIT_POINTER(keypairs->previous_keypair, NULL); noise_keypair_put(previous_keypair); } spin_unlock_bh(&keypairs->keypair_update_lock); @@ -220,7 +220,7 @@ bool noise_received_with_keypair(struct noise_keypairs *keypairs, struct noise_k rcu_assign_pointer(keypairs->previous_keypair, rcu_dereference_protected(keypairs->current_keypair, lockdep_is_held(&keypairs->keypair_update_lock))); noise_keypair_put(old_keypair); rcu_assign_pointer(keypairs->current_keypair, received_keypair); - rcu_assign_pointer(keypairs->next_keypair, NULL); + RCU_INIT_POINTER(keypairs->next_keypair, NULL); spin_unlock_bh(&keypairs->keypair_update_lock); return true; |