Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v2 1/2] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready()
@ 2026-09-10 18:12 Luiz Augusto von Dentz
  2026-09-10 18:12 ` [PATCH v2 2/2] Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync Luiz Augusto von Dentz
  2026-09-10 20:58 ` [v2,1/2] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready() bluez.test.bot
  0 siblings, 2 replies; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2026-09-10 18:12 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

iso_get_sock() returns the parent socket with a reference held, which is
dropped by sock_put() once the child socket has been set up. The error
path taken when iso_sock_alloc() fails only calls release_sock() and
returns, leaking the reference and thus the parent socket itself.

Drop the reference on that path as well.

Fixes: b9858430f759 ("Bluetooth: ISO: Fix possible UAF on iso_conn_free")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 net/bluetooth/iso.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 75bfd5938b2e..4de332b8901f 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -2289,6 +2289,7 @@ static void iso_conn_ready(struct iso_conn *conn)
 				    BTPROTO_ISO, GFP_ATOMIC, 0);
 		if (!sk) {
 			release_sock(parent);
+			sock_put(parent);
 			return;
 		}
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2 2/2] Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync
  2026-09-10 18:12 [PATCH v2 1/2] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready() Luiz Augusto von Dentz
@ 2026-09-10 18:12 ` Luiz Augusto von Dentz
  2026-09-10 20:58 ` [v2,1/2] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready() bluez.test.bot
  1 sibling, 0 replies; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2026-09-10 18:12 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

A BIS connection is matched to its parent socket by looking for a
socket in BT_LISTEN state with the same BIG handle:

  iso_conn_ready()
    if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags))
            parent = iso_get_sock(hdev, &hcon->src, &hcon->dst,
                                  BT_LISTEN, iso_match_big_hcon, hcon);

The socket was only moved to BT_LISTEN after iso_conn_big_sync()
returned, while the LE BIG Create Sync command has already been queued
by then. If the BIG sync is established before the state is updated,
which is easy to hit with an emulated controller as the command may
complete in a few hundred microseconds, no parent is found and the BIS
connections are never notified to the listening socket.

The user space is then left waiting for connections that never arrive,
e.g. bluetoothd never completes a MediaTransport1.Acquire of a
Broadcast Sink transport.

Move the socket to BT_LISTEN before requesting the BIG sync, so the
state is visible by the time the command is queued, and restore the
previous state if the request could not be started. Since the socket is
briefly visible as a listening socket, child sockets may have been
queued in the meantime, so drain the accept queue before restoring the
state: the cleanup paths of BT_CONNECT2/BT_CONNECTED don't do it and the
children would be left with a dangling parent pointer.

Fixes: fbdc4bc47268 ("Bluetooth: ISO: Use defer setup to separate PA sync and BIG sync")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 net/bluetooth/iso.c | 52 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 41 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 4de332b8901f..eb99653f33f9 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -819,19 +819,24 @@ static void iso_sock_destruct(struct sock *sk)
 	skb_queue_purge(&sk->sk_error_queue);
 }
 
-static void iso_sock_cleanup_listen(struct sock *parent)
+/* Close not yet accepted channels */
+static void iso_sock_flush_accept_q(struct sock *parent)
 {
 	struct sock *sk;
 
-	BT_DBG("parent %p", parent);
-
-	/* Close not yet accepted channels */
 	while ((sk = bt_accept_dequeue(parent, NULL))) {
 		iso_sock_close(sk);
 		iso_sock_kill(sk);
 		/* Drop the reference handed back by bt_accept_dequeue(). */
 		sock_put(sk);
 	}
+}
+
+static void iso_sock_cleanup_listen(struct sock *parent)
+{
+	BT_DBG("parent %p", parent);
+
+	iso_sock_flush_accept_q(parent);
 
 	/* If listening socket has a hcon, properly disconnect it */
 	if (iso_pi(parent)->conn && iso_pi(parent)->conn->hcon) {
@@ -1737,6 +1742,13 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
 		switch (sk->sk_state) {
 		case BT_CONNECT2:
 			if (test_bit(BT_SK_PA_SYNC, &pi->flags)) {
+				/* Move to BT_LISTEN before requesting the BIG
+				 * sync: the BIS connections are matched to a
+				 * parent socket in BT_LISTEN state, and they
+				 * may be notified before the request returns.
+				 */
+				sk->sk_state = BT_LISTEN;
+
 				release_sock(sk);
 				err = iso_conn_big_sync(sk);
 				lock_sock(sk);
@@ -1745,12 +1757,20 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
 				 * connection may have been torn down
 				 * meanwhile and iso_chan_del() may have
 				 * already moved the socket to BT_CLOSED.
-				 * Only move on to BT_LISTEN if the BIG sync
-				 * was actually started and nothing else has
-				 * changed the state.
+				 * Only move back if the BIG sync could not be
+				 * started and nothing else has changed the
+				 * state.
 				 */
-				if (!err && sk->sk_state == BT_CONNECT2)
-					sk->sk_state = BT_LISTEN;
+				if (err && sk->sk_state == BT_LISTEN) {
+					/* Discard any child socket that may
+					 * have been queued while the socket
+					 * was in BT_LISTEN, as the cleanup of
+					 * BT_CONNECT2 doesn't drain the
+					 * accept queue.
+					 */
+					iso_sock_flush_accept_q(sk);
+					sk->sk_state = BT_CONNECT2;
+				}
 			} else {
 				iso_conn_defer_accept(pi->conn->hcon);
 				sk->sk_state = BT_CONFIG;
@@ -1760,12 +1780,22 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
 			break;
 		case BT_CONNECTED:
 			if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
+				/* As above, the BIS connections may be
+				 * notified before the request returns.
+				 */
+				sk->sk_state = BT_LISTEN;
+
 				release_sock(sk);
 				err = iso_conn_big_sync(sk);
 				lock_sock(sk);
 
-				if (!err && sk->sk_state == BT_CONNECTED)
-					sk->sk_state = BT_LISTEN;
+				if (err && sk->sk_state == BT_LISTEN) {
+					/* As above, don't leave any child
+					 * socket behind in the accept queue.
+					 */
+					iso_sock_flush_accept_q(sk);
+					sk->sk_state = BT_CONNECTED;
+				}
 				early_ret = true;
 			}
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* RE: [v2,1/2] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready()
  2026-09-10 18:12 [PATCH v2 1/2] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready() Luiz Augusto von Dentz
  2026-09-10 18:12 ` [PATCH v2 2/2] Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync Luiz Augusto von Dentz
@ 2026-09-10 20:58 ` bluez.test.bot
  1 sibling, 0 replies; 3+ messages in thread
From: bluez.test.bot @ 2026-09-10 20:58 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz

[-- Attachment #1: Type: text/plain, Size: 1073 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/series/1162293/

---Test result---

Test Summary:
CheckPatch                    PASS      1.06 seconds
VerifyFixes                   PASS      0.07 seconds
VerifySignedoff               PASS      0.08 seconds
GitLint                       PASS      0.43 seconds
SubjectPrefix                 PASS      0.14 seconds
BuildKernel                   PASS      23.94 seconds
CheckAllWarning               PASS      27.45 seconds
CheckSparse                   PASS      29.57 seconds
BuildKernel32                 PASS      24.43 seconds
CheckKernelLLVM               PASS      24.86 seconds
TestRunnerSetup               PASS      598.80 seconds
TestRunner_iso-tester         PASS      63.84 seconds
IncrementalBuild              PASS      26.18 seconds



https://github.com/bluez/bluetooth-next/pull/751

---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-10 20:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-10 18:12 [PATCH v2 1/2] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready() Luiz Augusto von Dentz
2026-09-10 18:12 ` [PATCH v2 2/2] Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync Luiz Augusto von Dentz
2026-09-10 20:58 ` [v2,1/2] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready() bluez.test.bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox