]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Bluetooth: ISO: lock sk in iso_connect_ind
authorPauli Virtanen <pav@iki.fi>
Fri, 24 Jul 2026 20:20:26 +0000 (23:20 +0300)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 28 Jul 2026 20:13:11 +0000 (16:13 -0400)
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 <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
net/bluetooth/iso.c

index dbb8f43052f05722ffd625a6380dc8dccecf28b9..6516618339665a84b8cd751ef53f2cf7f9a6415c 100644 (file)
@@ -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);