aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/sock.h
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-10-18 00:22:42 -0400
committerDavid S. Miller <davem@davemloft.net>2007-10-18 00:22:42 -0400
commit47e958eac280c263397582d5581e868c3227a1bd (patch)
tree67fc50a26b7861b3330eae7f1874df851c0ef740 /include/net/sock.h
parentd3904b739928edd83d117f1eb5bfa69f18d6f046 (diff)
[NET]: Fix the race between sk_filter_(de|at)tach and sk_clone()
The proposed fix is to delay the reference counter decrement until the quiescent state pass. This will give sk_clone() a chance to get the reference on the cloned filter. Regular sk_filter_uncharge can happen from the sk_free() only and there's no need in delaying the put - the socket is dead anyway and is to be release itself. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/sock.h')
-rw-r--r--include/net/sock.h12
1 files changed, 1 insertions, 11 deletions
diff --git a/include/net/sock.h b/include/net/sock.h
index b9cfe125c9e6..43fc3fa50d62 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -905,16 +905,6 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb)
905} 905}
906 906
907/** 907/**
908 * sk_filter_rcu_free: Free a socket filter
909 * @rcu: rcu_head that contains the sk_filter to free
910 */
911static inline void sk_filter_rcu_free(struct rcu_head *rcu)
912{
913 struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
914 kfree(fp);
915}
916
917/**
918 * sk_filter_release: Release a socket filter 908 * sk_filter_release: Release a socket filter
919 * @sk: socket 909 * @sk: socket
920 * @fp: filter to remove 910 * @fp: filter to remove
@@ -925,7 +915,7 @@ static inline void sk_filter_rcu_free(struct rcu_head *rcu)
925static inline void sk_filter_release(struct sk_filter *fp) 915static inline void sk_filter_release(struct sk_filter *fp)
926{ 916{
927 if (atomic_dec_and_test(&fp->refcnt)) 917 if (atomic_dec_and_test(&fp->refcnt))
928 call_rcu_bh(&fp->rcu, sk_filter_rcu_free); 918 kfree(fp);
929} 919}
930 920
931static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp) 921static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)