aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/af_netlink.c
diff options
context:
space:
mode:
authorTommy S. Christensen <tommy.christensen@tpack.net>2005-05-19 15:46:59 -0400
committerDavid S. Miller <davem@davemloft.net>2005-05-19 15:46:59 -0400
commitdb61ecc3352d72513c1b07805bd6f760e30c001b (patch)
treec85af775fc7eccbb12501e0a8d42cd5d284e494d /net/netlink/af_netlink.c
parent1eda339e76a9aac05883c548028bf91aed734783 (diff)
[NETLINK]: Fix race with recvmsg().
This bug causes: assertion (!atomic_read(&sk->sk_rmem_alloc)) failed at net/netlink/af_netlink.c (122) What's happening is that: 1) The skb is sent to socket 1. 2) Someone does a recvmsg on socket 1 and drops the ref on the skb. Note that the rmalloc is not returned at this point since the skb is still referenced. 3) The same skb is now sent to socket 2. This version of the fix resurrects the skb_orphan call that was moved out, last time we had 'shared-skb troubles'. It is practically a no-op in the common case, but still prevents the possible race with recvmsg. Signed-off-by: Tommy S. Christensen <tommy.christensen@tpack.net> Acked-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r--net/netlink/af_netlink.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 733bf52cef3e..b40c9a976969 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -697,6 +697,7 @@ static __inline__ int netlink_broadcast_deliver(struct sock *sk, struct sk_buff
697 697
698 if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf && 698 if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
699 !test_bit(0, &nlk->state)) { 699 !test_bit(0, &nlk->state)) {
700 skb_orphan(skb);
700 skb_set_owner_r(skb, sk); 701 skb_set_owner_r(skb, sk);
701 skb_queue_tail(&sk->sk_receive_queue, skb); 702 skb_queue_tail(&sk->sk_receive_queue, skb);
702 sk->sk_data_ready(sk, skb->len); 703 sk->sk_data_ready(sk, skb->len);