diff options
| author | Pauli Virtanen <pav@iki.fi> | 2026-07-24 23:20:26 +0300 |
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2026-07-27 11:54:09 -0400 |
| commit | df810355bbe7ef03368563e8325783b17421df95 (patch) | |
| tree | bd98e2d5dcd8b25db3b9dd5b1c601b4a394cff6d | |
| parent | 6d16b799d7f4af61f923fd5e66a3c926add7ac22 (diff) | |
| download | linux-next-df810355bbe7ef03368563e8325783b17421df95.tar.gz linux-next-df810355bbe7ef03368563e8325783b17421df95.zip | |
Bluetooth: ISO: lock sk in iso_connect_ind
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>
| -rw-r--r-- | net/bluetooth/iso.c | 19 |
1 files 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); |
