]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
net: fix a race in sock_queue_err_skb()
authorEric Dumazet <eric.dumazet@gmail.com>
Fri, 6 Apr 2012 08:49:10 +0000 (10:49 +0200)
committerBen Hutchings <ben@decadent.org.uk>
Fri, 11 May 2012 12:14:21 +0000 (13:14 +0100)
[ Upstream commit 110c43304db6f06490961529536c362d9ac5732f ]

As soon as an skb is queued into socket error queue, another thread
can consume it, so we are not allowed to reference skb anymore, or risk
use after free.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
net/core/skbuff.c

index 3c30ee4a57105a2746b3e1b2bfab68af8ef0c917..29cb3924fdf6806527ca327c88f4e3587f5859d5 100644 (file)
@@ -3111,6 +3111,8 @@ static void sock_rmem_free(struct sk_buff *skb)
  */
 int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
 {
+       int len = skb->len;
+
        if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
            (unsigned)sk->sk_rcvbuf)
                return -ENOMEM;
@@ -3125,7 +3127,7 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
 
        skb_queue_tail(&sk->sk_error_queue, skb);
        if (!sock_flag(sk, SOCK_DEAD))
-               sk->sk_data_ready(sk, skb->len);
+               sk->sk_data_ready(sk, len);
        return 0;
 }
 EXPORT_SYMBOL(sock_queue_err_skb);