net: sk_{detach|attach}_filter() rcu fixes
sk_attach_filter() and sk_detach_filter() are run with socket locked. Use the appropriate rcu_dereference_protected() instead of blocking BH, and rcu_dereference_bh(). There is no point adding BH prevention and memory barrier. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
7fa7cb7109
commit
f91ff5b9ff
|
@ -638,10 +638,9 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
|
|||
return err;
|
||||
}
|
||||
|
||||
rcu_read_lock_bh();
|
||||
old_fp = rcu_dereference_bh(sk->sk_filter);
|
||||
old_fp = rcu_dereference_protected(sk->sk_filter,
|
||||
sock_owned_by_user(sk));
|
||||
rcu_assign_pointer(sk->sk_filter, fp);
|
||||
rcu_read_unlock_bh();
|
||||
|
||||
if (old_fp)
|
||||
sk_filter_delayed_uncharge(sk, old_fp);
|
||||
|
@ -654,14 +653,13 @@ int sk_detach_filter(struct sock *sk)
|
|||
int ret = -ENOENT;
|
||||
struct sk_filter *filter;
|
||||
|
||||
rcu_read_lock_bh();
|
||||
filter = rcu_dereference_bh(sk->sk_filter);
|
||||
filter = rcu_dereference_protected(sk->sk_filter,
|
||||
sock_owned_by_user(sk));
|
||||
if (filter) {
|
||||
rcu_assign_pointer(sk->sk_filter, NULL);
|
||||
sk_filter_delayed_uncharge(sk, filter);
|
||||
ret = 0;
|
||||
}
|
||||
rcu_read_unlock_bh();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sk_detach_filter);
|
||||
|
|
Loading…
Reference in a new issue