From 67dc13388b11f007fd0fa0e662e304dcde9e8b9f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 25 Oct 2010 03:47:05 +0000 Subject: [PATCH] --- yaml --- r: 218420 b: refs/heads/master c: 0d7da9ddd9a4eb7808698d04b98bf9d62d02649b h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/net/sock.h | 2 +- trunk/net/core/filter.c | 4 ++-- trunk/net/core/sock.c | 2 +- trunk/net/ipv4/udp.c | 2 +- trunk/net/ipv6/raw.c | 2 +- trunk/net/ipv6/udp.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index d65ce76d47ce..a5e68ff13b24 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1c87733d0682547050ccccb400cdac425fa43b39 +refs/heads/master: 0d7da9ddd9a4eb7808698d04b98bf9d62d02649b diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 73a4f9702a65..c7a736228ca2 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -301,7 +301,7 @@ struct sock { const struct cred *sk_peer_cred; long sk_rcvtimeo; long sk_sndtimeo; - struct sk_filter *sk_filter; + struct sk_filter __rcu *sk_filter; void *sk_protinfo; struct timer_list sk_timer; ktime_t sk_stamp; diff --git a/trunk/net/core/filter.c b/trunk/net/core/filter.c index 7adf50352918..7beaec36b541 100644 --- a/trunk/net/core/filter.c +++ b/trunk/net/core/filter.c @@ -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(); diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index 11db43632df8..3eed5424e659 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -1225,7 +1225,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) sock_reset_flag(newsk, SOCK_DONE); skb_queue_head_init(&newsk->sk_error_queue); - filter = newsk->sk_filter; + filter = rcu_dereference_protected(newsk->sk_filter, 1); if (filter != NULL) sk_filter_charge(newsk, filter); diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index b3f7e8cf18ac..28cb2d733a3c 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -1413,7 +1413,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) } } - if (sk->sk_filter) { + if (rcu_dereference_raw(sk->sk_filter)) { if (udp_lib_checksum_complete(skb)) goto drop; } diff --git a/trunk/net/ipv6/raw.c b/trunk/net/ipv6/raw.c index 45e6efb7f171..86c39526ba5e 100644 --- a/trunk/net/ipv6/raw.c +++ b/trunk/net/ipv6/raw.c @@ -373,7 +373,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr, static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) { - if ((raw6_sk(sk)->checksum || sk->sk_filter) && + if ((raw6_sk(sk)->checksum || rcu_dereference_raw(sk->sk_filter)) && skb_checksum_complete(skb)) { atomic_inc(&sk->sk_drops); kfree_skb(skb); diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index c84dad432114..91def93bec85 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -527,7 +527,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) } } - if (sk->sk_filter) { + if (rcu_dereference_raw(sk->sk_filter)) { if (udp_lib_checksum_complete(skb)) goto drop; }