* [PATCH v2 1/2 5.10.y] Bluetooth: SCO: Fix UAF on sco_sock_timeout
@ 2026-08-05 21:24 Todd Kjos
2026-08-05 21:24 ` [PATCH v2 2/2 5.10.y] Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold Todd Kjos
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Todd Kjos @ 2026-08-05 21:24 UTC (permalink / raw)
To: stable
Cc: kernel-team, Lee Jones, Marcel Holtmann, Johan Hedberg,
David S . Miller, Jakub Kicinski, linux-bluetooth, netdev,
Luiz Augusto von Dentz, syzbot+4c0d0c4cde787116d465, Xiangyu Chen,
He Zhe, Greg Kroah-Hartman, Todd Kjos
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
commit 1bf4470a3939c678fb822073e9ea77a0560bc6bb upstream.
conn->sk maybe have been unlinked/freed while waiting for sco_conn_lock
so this checks if the conn->sk is still valid by checking if it part of
sco_sk_list.
Reported-by: syzbot+4c0d0c4cde787116d465@syzkaller.appspotmail.com
Tested-by: syzbot+4c0d0c4cde787116d465@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=4c0d0c4cde787116d465
Fixes: ba316be1b6a0 ("Bluetooth: schedule SCO timeouts with delayed_work")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
Signed-off-by: He Zhe <zhe.he@windriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ Resolved trivial conflicts in net/bluetooth/sco.c, removed
extra reference on sk ]
Signed-off-by: Todd Kjos <tkjos@google.com>
---
Changes in v2:
- Removed redundant reference on struct sock
- Removed Change-Id tags
include/net/bluetooth/bluetooth.h | 1 +
net/bluetooth/af_bluetooth.c | 22 ++++++++++++++++++++++
net/bluetooth/sco.c | 17 ++++++++++++-----
3 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 43b4386018e26c41c914f87e050a0fe958700135..85bab90a6921ce1e9b9025647e23fafd97117ece 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -317,6 +317,7 @@ void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
struct sock *bt_sock_alloc(struct net *net, struct socket *sock,
struct proto *prot, int proto, gfp_t prio, int kern);
+bool bt_sock_linked(struct bt_sock_list *l, struct sock *s);
int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
int flags);
int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg,
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index bef5b6330dd807504292671301c860b96c2ed18e..0af14e3318e7e02173970a1af8e183723bef2c50 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -184,6 +184,28 @@ void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
}
EXPORT_SYMBOL(bt_sock_unlink);
+bool bt_sock_linked(struct bt_sock_list *l, struct sock *s)
+{
+ struct sock *sk;
+
+ if (!l || !s)
+ return false;
+
+ read_lock(&l->lock);
+
+ sk_for_each(sk, &l->head) {
+ if (s == sk) {
+ read_unlock(&l->lock);
+ return true;
+ }
+ }
+
+ read_unlock(&l->lock);
+
+ return false;
+}
+EXPORT_SYMBOL(bt_sock_linked);
+
void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh)
{
const struct cred *old_cred;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 01a01d6f01c309a6333859784261d97335dda413..2fbd9c93440ce4936d47b3bd47aa1dc28da82c20 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -76,6 +76,16 @@ struct sco_pinfo {
#define SCO_CONN_TIMEOUT (HZ * 40)
#define SCO_DISCONN_TIMEOUT (HZ * 2)
+static struct sock *sco_sock_hold(struct sco_conn *conn)
+{
+ if (!conn || !bt_sock_linked(&sco_sk_list, conn->sk))
+ return NULL;
+
+ sock_hold(conn->sk);
+
+ return conn->sk;
+}
+
static void sco_sock_timeout(struct work_struct *work)
{
struct sco_conn *conn = container_of(work, struct sco_conn,
@@ -87,9 +97,7 @@ static void sco_sock_timeout(struct work_struct *work)
sco_conn_unlock(conn);
return;
}
- sk = conn->sk;
- if (sk)
- sock_hold(sk);
+ sk = sco_sock_hold(conn);
sco_conn_unlock(conn);
if (!sk)
@@ -192,11 +200,10 @@ static void sco_conn_del(struct hci_conn *hcon, int err)
/* Kill socket */
sco_conn_lock(conn);
- sk = conn->sk;
+ sk = sco_sock_hold(conn);
sco_conn_unlock(conn);
if (sk) {
- sock_hold(sk);
bh_lock_sock(sk);
sco_sock_clear_timer(sk);
sco_chan_del(sk, err);
--
2.55.0.629.g250fe7f194-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v2 2/2 5.10.y] Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold
2026-08-05 21:24 [PATCH v2 1/2 5.10.y] Bluetooth: SCO: Fix UAF on sco_sock_timeout Todd Kjos
@ 2026-08-05 21:24 ` Todd Kjos
2026-08-05 21:52 ` [v2,1/2,5.10.y] Bluetooth: SCO: Fix UAF on sco_sock_timeout bluez.test.bot
2026-08-06 11:36 ` [PATCH v2 1/2 5.10.y] " Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: Todd Kjos @ 2026-08-05 21:24 UTC (permalink / raw)
To: stable
Cc: kernel-team, Lee Jones, Marcel Holtmann, Johan Hedberg,
David S . Miller, Jakub Kicinski, linux-bluetooth, netdev,
Hyunwoo Kim, Luiz Augusto von Dentz, Sasha Levin, Todd Kjos
From: Hyunwoo Kim <imv4bel@gmail.com>
[ Upstream commit 598dbba9919c5e36c54fe1709b557d64120cb94b ]
sco_recv_frame() reads conn->sk under sco_conn_lock() but immediately
releases the lock without holding a reference to the socket. A concurrent
close() can free the socket between the lock release and the subsequent
sk->sk_state access, resulting in a use-after-free.
Other functions in the same file (sco_sock_timeout(), sco_conn_del())
correctly use sco_sock_hold() to safely hold a reference under the lock.
Fix by using sco_sock_hold() to take a reference before releasing the
lock, and adding sock_put() on all exit paths.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Todd Kjos <tkjos@google.com>
---
net/bluetooth/sco.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 2fbd9c93440ce4936d47b3bd47aa1dc28da82c20..b49b2d6bb778e8956d4a297c9feecadd1557a3b9 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -312,7 +312,7 @@ static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
struct sock *sk;
sco_conn_lock(conn);
- sk = conn->sk;
+ sk = sco_sock_hold(conn);
sco_conn_unlock(conn);
if (!sk)
@@ -321,11 +321,15 @@ static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
BT_DBG("sk %p len %d", sk, skb->len);
if (sk->sk_state != BT_CONNECTED)
- goto drop;
+ goto drop_put;
- if (!sock_queue_rcv_skb(sk, skb))
+ if (!sock_queue_rcv_skb(sk, skb)) {
+ sock_put(sk);
return;
+ }
+drop_put:
+ sock_put(sk);
drop:
kfree_skb(skb);
}
--
2.55.0.629.g250fe7f194-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread* RE: [v2,1/2,5.10.y] Bluetooth: SCO: Fix UAF on sco_sock_timeout
2026-08-05 21:24 [PATCH v2 1/2 5.10.y] Bluetooth: SCO: Fix UAF on sco_sock_timeout Todd Kjos
2026-08-05 21:24 ` [PATCH v2 2/2 5.10.y] Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold Todd Kjos
@ 2026-08-05 21:52 ` bluez.test.bot
2026-08-06 11:36 ` [PATCH v2 1/2 5.10.y] " Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: bluez.test.bot @ 2026-08-05 21:52 UTC (permalink / raw)
To: linux-bluetooth, tkjos
[-- Attachment #1: Type: text/plain, Size: 773 bytes --]
This is an automated email and please do not reply to this email.
Dear Submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.
----- Output -----
error: patch failed: include/net/bluetooth/bluetooth.h:317
error: include/net/bluetooth/bluetooth.h: patch does not apply
error: patch failed: net/bluetooth/af_bluetooth.c:184
error: net/bluetooth/af_bluetooth.c: patch does not apply
error: patch failed: net/bluetooth/sco.c:76
error: net/bluetooth/sco.c: patch does not apply
hint: Use 'git am --show-current-patch' to see the failed patch
Please resolve the issue and submit the patches again.
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2 1/2 5.10.y] Bluetooth: SCO: Fix UAF on sco_sock_timeout
2026-08-05 21:24 [PATCH v2 1/2 5.10.y] Bluetooth: SCO: Fix UAF on sco_sock_timeout Todd Kjos
2026-08-05 21:24 ` [PATCH v2 2/2 5.10.y] Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold Todd Kjos
2026-08-05 21:52 ` [v2,1/2,5.10.y] Bluetooth: SCO: Fix UAF on sco_sock_timeout bluez.test.bot
@ 2026-08-06 11:36 ` Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-08-06 11:36 UTC (permalink / raw)
To: stable
Cc: Sasha Levin, kernel-team, Lee Jones, Marcel Holtmann,
Johan Hedberg, David S . Miller, Jakub Kicinski, linux-bluetooth,
netdev, Luiz Augusto von Dentz, syzbot+4c0d0c4cde787116d465,
Xiangyu Chen, He Zhe, Greg Kroah-Hartman, Todd Kjos
On Wed, Aug 05, 2026 at 09:24:34PM +0000, Todd Kjos wrote:
> Changes in v2:
> - Removed redundant reference on struct sock
> - Removed Change-Id tags
Queued the series for 5.10, thanks.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-06 11:36 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-05 21:24 [PATCH v2 1/2 5.10.y] Bluetooth: SCO: Fix UAF on sco_sock_timeout Todd Kjos
2026-08-05 21:24 ` [PATCH v2 2/2 5.10.y] Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold Todd Kjos
2026-08-05 21:52 ` [v2,1/2,5.10.y] Bluetooth: SCO: Fix UAF on sco_sock_timeout bluez.test.bot
2026-08-06 11:36 ` [PATCH v2 1/2 5.10.y] " Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox