[PATCH 03/11] Bluetooth: ISO: lock sk in iso_connect_ind
Pauli Virtanen <[email protected]> Fri, 24 Jul 2026 23:20:26 +0300
| Newsgroups | org.kernel.vger.linux-bluetooth,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <b7443b1e6093867fab5168677f6474e037e59f97.1784923689.git.pav@iki.fi> |
Accessing iso_pi(sk)->conn requires lock_sock, which is not taken in the
"ev3" part of iso_connect_ind. It may also be NULL if socket has
transitioned away from the LISTEN/CONNECT states before locking.
Fix by adding lock/release. Recheck hcon is valid after lock acquire
where needed.
Fixes: 168d9bf9c7f0 ("Bluetooth: ISO: Reassemble PA data for bcast sink")
Signed-off-by: Pauli Virtanen <[email protected]>
---
net/bluetooth/iso.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index dbb8f43052f0..651661833966 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -2369,7 +2369,7 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
lock_sock(sk);
- hcon = iso_pi(sk)->conn->hcon;
+ hcon = iso_pi(sk)->conn ? iso_pi(sk)->conn->hcon : NULL;
iso_pi(sk)->qos.bcast.encryption = ev2->encryption;
if (ev2->num_bis < iso_pi(sk)->bc_num_bis)
@@ -2409,9 +2409,11 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
if (!sk)
goto done;
- hcon = iso_pi(sk)->conn->hcon;
+ lock_sock(sk);
+
+ hcon = iso_pi(sk)->conn ? iso_pi(sk)->conn->hcon : NULL;
if (!hcon)
- goto done;
+ goto release3;
if (ev3->data_status == LE_PA_DATA_TRUNCATED) {
/* The controller was unable to retrieve PA data. */
@@ -2419,12 +2421,12 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
HCI_MAX_PER_AD_TOT_LEN);
hcon->le_per_adv_data_len = 0;
hcon->le_per_adv_data_offset = 0;
- goto done;
+ goto release3;
}
if (hcon->le_per_adv_data_offset + ev3->length >
HCI_MAX_PER_AD_TOT_LEN)
- goto done;
+ goto release3;
memcpy(hcon->le_per_adv_data + hcon->le_per_adv_data_offset,
ev3->data, ev3->length);
@@ -2443,18 +2445,19 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
&base_len);
if (!base || base_len > BASE_MAX_LENGTH)
- goto done;
+ goto release3;
- lock_sock(sk);
memcpy(iso_pi(sk)->base, base, base_len);
iso_pi(sk)->base_len = base_len;
- release_sock(sk);
} else {
/* This is a PA data fragment. Keep pa_data_len set to 0
* until all data has been reassembled.
*/
hcon->le_per_adv_data_len = 0;
}
+
+release3:
+ release_sock(sk);
} else {
sk = iso_get_sock(hdev, &hdev->bdaddr, BDADDR_ANY,
BT_LISTEN, iso_match_dst, BDADDR_ANY);
--
2.55.0