Skip to content

Commit f9ecc90

Browse files
Vudentzgregkh
authored andcommitted
Bluetooth: hci_event: Fix using rcu_read_(un)lock while iterating
[ Upstream commit 581dd2d ] The usage of rcu_read_(un)lock while inside list_for_each_entry_rcu is not safe since for the most part entries fetched this way shall be treated as rcu_dereference: Note that the value returned by rcu_dereference() is valid only within the enclosing RCU read-side critical section [1]_. For example, the following is **not** legal:: rcu_read_lock(); p = rcu_dereference(head.next); rcu_read_unlock(); x = p->address; /* BUG!!! */ rcu_read_lock(); y = p->data; /* BUG!!! */ rcu_read_unlock(); Fixes: a0bfde1 ("Bluetooth: ISO: Add support for connecting multiple BISes") Signed-off-by: Luiz Augusto von Dentz <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 458aa67 commit f9ecc90

File tree

1 file changed

+11
-22
lines changed

1 file changed

+11
-22
lines changed

net/bluetooth/hci_event.c

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6872,38 +6872,27 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
68726872
return;
68736873

68746874
hci_dev_lock(hdev);
6875-
rcu_read_lock();
68766875

68776876
/* Connect all BISes that are bound to the BIG */
6878-
list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
6879-
if (bacmp(&conn->dst, BDADDR_ANY) ||
6880-
conn->type != ISO_LINK ||
6881-
conn->iso_qos.bcast.big != ev->handle)
6877+
while ((conn = hci_conn_hash_lookup_big_state(hdev, ev->handle,
6878+
BT_BOUND))) {
6879+
if (ev->status) {
6880+
hci_connect_cfm(conn, ev->status);
6881+
hci_conn_del(conn);
68826882
continue;
6883+
}
68836884

68846885
if (hci_conn_set_handle(conn,
68856886
__le16_to_cpu(ev->bis_handle[i++])))
68866887
continue;
68876888

6888-
if (!ev->status) {
6889-
conn->state = BT_CONNECTED;
6890-
set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
6891-
rcu_read_unlock();
6892-
hci_debugfs_create_conn(conn);
6893-
hci_conn_add_sysfs(conn);
6894-
hci_iso_setup_path(conn);
6895-
rcu_read_lock();
6896-
continue;
6897-
}
6898-
6899-
hci_connect_cfm(conn, ev->status);
6900-
rcu_read_unlock();
6901-
hci_conn_del(conn);
6902-
rcu_read_lock();
6889+
conn->state = BT_CONNECTED;
6890+
set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
6891+
hci_debugfs_create_conn(conn);
6892+
hci_conn_add_sysfs(conn);
6893+
hci_iso_setup_path(conn);
69036894
}
69046895

6905-
rcu_read_unlock();
6906-
69076896
if (!ev->status && !i)
69086897
/* If no BISes have been connected for the BIG,
69096898
* terminate. This is in case all bound connections

0 commit comments

Comments
 (0)