lkml.org 
[lkml]   [2021]   [Sep]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 063/175] Bluetooth: fix repeated calls to sco_sock_kill
    Date
    From: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>

    [ Upstream commit e1dee2c1de2b4dd00eb44004a4bda6326ed07b59 ]

    In commit 4e1a720d0312 ("Bluetooth: avoid killing an already killed
    socket"), a check was added to sco_sock_kill to skip killing a socket
    if the SOCK_DEAD flag was set.

    This was done after a trace for a use-after-free bug showed that the
    same sock pointer was being killed twice.

    Unfortunately, this check prevents sco_sock_kill from running on any
    socket. sco_sock_kill kills a socket only if it's zapped and orphaned,
    however sock_orphan announces that the socket is dead before detaching
    it. i.e., orphaned sockets have the SOCK_DEAD flag set.

    To fix this, we remove the check for SOCK_DEAD, and avoid repeated
    calls to sco_sock_kill by removing incorrect calls in:

    1. sco_sock_timeout. The socket should not be killed on timeout as
    further processing is expected to be done. For example,
    sco_sock_connect sets the timer then waits for the socket to be
    connected or for an error to be returned.

    2. sco_conn_del. This function should clean up resources for the
    connection, but the socket itself should be cleaned up in
    sco_sock_release.

    3. sco_sock_close. Calls to sco_sock_close in sco_sock_cleanup_listen
    and sco_sock_release are followed by sco_sock_kill. Hence the
    duplicated call should be removed.

    Fixes: 4e1a720d0312 ("Bluetooth: avoid killing an already killed socket")
    Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
    Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/bluetooth/sco.c | 6 +-----
    1 file changed, 1 insertion(+), 5 deletions(-)

    diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
    index 3174eab6eafc..70eb28df20d3 100644
    --- a/net/bluetooth/sco.c
    +++ b/net/bluetooth/sco.c
    @@ -83,7 +83,6 @@ static void sco_sock_timeout(unsigned long arg)
    sk->sk_state_change(sk);
    bh_unlock_sock(sk);

    - sco_sock_kill(sk);
    sock_put(sk);
    }

    @@ -175,7 +174,6 @@ static void sco_conn_del(struct hci_conn *hcon, int err)
    sco_sock_clear_timer(sk);
    sco_chan_del(sk, err);
    bh_unlock_sock(sk);
    - sco_sock_kill(sk);
    sock_put(sk);
    }

    @@ -392,8 +390,7 @@ static void sco_sock_cleanup_listen(struct sock *parent)
    */
    static void sco_sock_kill(struct sock *sk)
    {
    - if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket ||
    - sock_flag(sk, SOCK_DEAD))
    + if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
    return;

    BT_DBG("sk %p state %d", sk, sk->sk_state);
    @@ -445,7 +442,6 @@ static void sco_sock_close(struct sock *sk)
    lock_sock(sk);
    __sco_sock_close(sk);
    release_sock(sk);
    - sco_sock_kill(sk);
    }

    static void sco_sock_init(struct sock *sk, struct sock *parent)
    --
    2.30.2


    \
     
     \ /
      Last update: 2021-09-20 19:07    [W:4.400 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site