]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerPaul Gortmaker <paul.gortmaker@windriver.com>
Mon, 10 Feb 2014 21:10:55 +0000 (16:10 -0500)
commit 110c43304db6f06490961529536c362d9ac5732f upstream.

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>
[PG: net/core/skbuff.c  -->  include/net/sock.h on 2.6.34 baseline]
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
include/net/sock.h

index b365fc2597c3a48c2624808ac89479b62c77ee00..133e350c6fa3b239978ce70cf524d501d7f0779e 100644 (file)
@@ -1428,6 +1428,8 @@ extern int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
 
 static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
 {
+       int len = skb->len;
+
        /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
           number of warnings when compiling with -W --ANK
         */
@@ -1437,7 +1439,7 @@ static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
        skb_set_owner_r(skb, sk);
        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;
 }