]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/core/filter.c
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx
[net-next-2.6.git] / net / core / filter.c
index 52b051f82a016e37c792efc8bc30dca3d71fd537..7beaec36b541274bcd1d62c9fe8376b368ab3386 100644 (file)
@@ -89,8 +89,8 @@ int sk_filter(struct sock *sk, struct sk_buff *skb)
        rcu_read_lock_bh();
        filter = rcu_dereference_bh(sk->sk_filter);
        if (filter) {
-               unsigned int pkt_len = sk_run_filter(skb, filter->insns,
-                               filter->len);
+               unsigned int pkt_len = sk_run_filter(skb, filter->insns, filter->len);
+
                err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM;
        }
        rcu_read_unlock_bh();
@@ -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);