lkml.org 
[lkml]   [2015]   [Jun]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.19.y-ckt 136/146] unix/caif: sk_socket can disappear when state is unlocked
    Date
    3.19.8-ckt2 -stable review patch.  If anyone has any objections, please let me know.

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

    From: Mark Salyzyn <salyzyn@android.com>

    [ Upstream commit b48732e4a48d80ed4a14812f0bab09560846514e ]

    got a rare NULL pointer dereference in clear_bit

    Signed-off-by: Mark Salyzyn <salyzyn@android.com>
    Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
    ----
    v2: switch to sock_flag(sk, SOCK_DEAD) and added net/caif/caif_socket.c
    v3: return -ECONNRESET in upstream caller of wait function for SOCK_DEAD
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    net/caif/caif_socket.c | 8 ++++++++
    net/unix/af_unix.c | 8 ++++++++
    2 files changed, 16 insertions(+)

    diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
    index a6e2da0..982101c 100644
    --- a/net/caif/caif_socket.c
    +++ b/net/caif/caif_socket.c
    @@ -330,6 +330,10 @@ static long caif_stream_data_wait(struct sock *sk, long timeo)
    release_sock(sk);
    timeo = schedule_timeout(timeo);
    lock_sock(sk);
    +
    + if (sock_flag(sk, SOCK_DEAD))
    + break;
    +
    clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
    }

    @@ -374,6 +378,10 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
    struct sk_buff *skb;

    lock_sock(sk);
    + if (sock_flag(sk, SOCK_DEAD)) {
    + err = -ECONNRESET;
    + goto unlock;
    + }
    skb = skb_dequeue(&sk->sk_receive_queue);
    caif_check_flow_release(sk);

    diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
    index 8e1b102..a8b4284 100644
    --- a/net/unix/af_unix.c
    +++ b/net/unix/af_unix.c
    @@ -1898,6 +1898,10 @@ static long unix_stream_data_wait(struct sock *sk, long timeo,
    unix_state_unlock(sk);
    timeo = freezable_schedule_timeout(timeo);
    unix_state_lock(sk);
    +
    + if (sock_flag(sk, SOCK_DEAD))
    + break;
    +
    clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
    }

    @@ -1962,6 +1966,10 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
    struct sk_buff *skb, *last;

    unix_state_lock(sk);
    + if (sock_flag(sk, SOCK_DEAD)) {
    + err = -ECONNRESET;
    + goto unlock;
    + }
    last = skb = skb_peek(&sk->sk_receive_queue);
    again:
    if (skb == NULL) {
    --
    1.9.1


    \
     
     \ /
      Last update: 2015-06-18 01:21    [W:6.370 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site