summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDesmond Cheong Zhi Xi <desmondcheongzx@gmail.com>2021-08-10 12:14:10 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-09-22 11:47:53 +0200
commitbc4b08383046f3282b6fa58cfcef05bd13e52b93 (patch)
tree04835df3ea423eab249c75c3d040100045ad107a /net
parente751dfbab446815a204796c1392f7dffcfa86221 (diff)
downloadlinux-stable-bc4b08383046f3282b6fa58cfcef05bd13e52b93.tar.gz
linux-stable-bc4b08383046f3282b6fa58cfcef05bd13e52b93.tar.bz2
linux-stable-bc4b08383046f3282b6fa58cfcef05bd13e52b93.zip
Bluetooth: fix repeated calls to sco_sock_kill
[ 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>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/sco.c6
1 files changed, 1 insertions, 5 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 2561e462400e..2fbea653540b 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -84,7 +84,6 @@ static void sco_sock_timeout(struct timer_list *t)
sk->sk_state_change(sk);
bh_unlock_sock(sk);
- sco_sock_kill(sk);
sock_put(sk);
}
@@ -176,7 +175,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);
}
@@ -393,8 +391,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);
@@ -446,7 +443,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)