lkml.org 
[lkml]   [2012]   [May]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[ 070/167] [PATCH 10/26] netlink: fix races after skb queueing
    3.2-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Eric Dumazet <eric.dumazet@gmail.com>

    [ Upstream commit 4a7e7c2ad540e54c75489a70137bf0ec15d3a127 ]

    As soon as an skb is queued into socket receive_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/netlink/af_netlink.c | 24 +++++++++++++-----------
    1 file changed, 13 insertions(+), 11 deletions(-)

    diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
    index 1201b6d..a99fb41 100644
    --- a/net/netlink/af_netlink.c
    +++ b/net/netlink/af_netlink.c
    @@ -830,12 +830,19 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
    return 0;
    }

    -int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
    +static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
    {
    int len = skb->len;

    skb_queue_tail(&sk->sk_receive_queue, skb);
    sk->sk_data_ready(sk, len);
    + return len;
    +}
    +
    +int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
    +{
    + int len = __netlink_sendskb(sk, skb);
    +
    sock_put(sk);
    return len;
    }
    @@ -960,8 +967,7 @@ static inline int netlink_broadcast_deliver(struct sock *sk,
    if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
    !test_bit(0, &nlk->state)) {
    skb_set_owner_r(skb, sk);
    - skb_queue_tail(&sk->sk_receive_queue, skb);
    - sk->sk_data_ready(sk, skb->len);
    + __netlink_sendskb(sk, skb);
    return atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf;
    }
    return -1;
    @@ -1684,10 +1690,8 @@ static int netlink_dump(struct sock *sk)

    if (sk_filter(sk, skb))
    kfree_skb(skb);
    - else {
    - skb_queue_tail(&sk->sk_receive_queue, skb);
    - sk->sk_data_ready(sk, skb->len);
    - }
    + else
    + __netlink_sendskb(sk, skb);
    return 0;
    }

    @@ -1701,10 +1705,8 @@ static int netlink_dump(struct sock *sk)

    if (sk_filter(sk, skb))
    kfree_skb(skb);
    - else {
    - skb_queue_tail(&sk->sk_receive_queue, skb);
    - sk->sk_data_ready(sk, skb->len);
    - }
    + else
    + __netlink_sendskb(sk, skb);

    if (cb->done)
    cb->done(cb);
    --
    1.7.10




    \
     
     \ /
      Last update: 2012-05-09 09:02    [W:0.046 / U:29.900 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site