Skip to content

Commit 0108132

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 11dc486 commit 0108132

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
@@ -6821,38 +6821,27 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
68216821
return;
68226822

68236823
hci_dev_lock(hdev);
6824-
rcu_read_lock();
68256824

68266825
/* Connect all BISes that are bound to the BIG */
6827-
list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
6828-
if (bacmp(&conn->dst, BDADDR_ANY) ||
6829-
conn->type != ISO_LINK ||
6830-
conn->iso_qos.bcast.big != ev->handle)
6826+
while ((conn = hci_conn_hash_lookup_big_state(hdev, ev->handle,
6827+
BT_BOUND))) {
6828+
if (ev->status) {
6829+
hci_connect_cfm(conn, ev->status);
6830+
hci_conn_del(conn);
68316831
continue;
6832+
}
68326833

68336834
if (hci_conn_set_handle(conn,
68346835
__le16_to_cpu(ev->bis_handle[i++])))
68356836
continue;
68366837

6837-
if (!ev->status) {
6838-
conn->state = BT_CONNECTED;
6839-
set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
6840-
rcu_read_unlock();
6841-
hci_debugfs_create_conn(conn);
6842-
hci_conn_add_sysfs(conn);
6843-
hci_iso_setup_path(conn);
6844-
rcu_read_lock();
6845-
continue;
6846-
}
6847-
6848-
hci_connect_cfm(conn, ev->status);
6849-
rcu_read_unlock();
6850-
hci_conn_del(conn);
6851-
rcu_read_lock();
6838+
conn->state = BT_CONNECTED;
6839+
set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
6840+
hci_debugfs_create_conn(conn);
6841+
hci_conn_add_sysfs(conn);
6842+
hci_iso_setup_path(conn);
68526843
}
68536844

6854-
rcu_read_unlock();
6855-
68566845
if (!ev->status && !i)
68576846
/* If no BISes have been connected for the BIG,
68586847
* terminate. This is in case all bound connections

0 commit comments

Comments
 (0)