diff mbox series

[RFC,5/5] Bluetooth: ISO: fix locking in iso_conn_ready

Message ID b0eab0121b79c3cb5c1abae958cafd102440897b.1687525956.git.pav@iki.fi (mailing list archive)
State New, archived
Headers show
Series hci_conn and ISO concurrency fixes | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint success Gitlint PASS
tedd_an/SubjectPrefix success Gitlint PASS
tedd_an/IncrementalBuild success Incremental Build PASS

Commit Message

Pauli Virtanen June 23, 2023, 5:18 p.m. UTC
Getting conn->sk must sock_hold, otherwise the socket may be freed
concurrently.  Access to conn->hcon is safe when holding hdev->lock.

Fix the locking in iso_conn_ready to obey this.

Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
 net/bluetooth/iso.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index ea0209fb9872..c2045adbd7b6 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -179,6 +179,7 @@  static void iso_chan_del(struct sock *sk, int err)
 	sock_set_flag(sk, SOCK_ZAPPED);
 }
 
+/* Must hold hdev->lock */
 static void iso_conn_del(struct hci_conn *hcon, int err)
 {
 	struct iso_conn *conn = hcon->iso_data;
@@ -1547,19 +1548,23 @@  static bool iso_match_big(struct sock *sk, void *data)
 static void iso_conn_ready(struct iso_conn *conn)
 {
 	struct sock *parent;
-	struct sock *sk = conn->sk;
+	struct sock *sk;
 	struct hci_ev_le_big_sync_estabilished *ev;
 	struct hci_conn *hcon;
 
 	BT_DBG("conn %p", conn);
 
-	if (sk) {
-		iso_sock_ready(conn->sk);
-	} else {
-		hcon = conn->hcon;
-		if (!hcon)
-			return;
+	iso_conn_lock(conn);
+	hcon = conn->hcon;
+	sk = conn->sk;
+	if (sk)
+		sock_hold(sk);
+	iso_conn_unlock(conn);
 
+	if (sk) {
+		iso_sock_ready(sk);
+		sock_put(sk);
+	} else if (hcon) {
 		ev = hci_recv_event_data(hcon->hdev,
 					 HCI_EVT_LE_BIG_SYNC_ESTABILISHED);
 		if (ev)