Re: [syzbot] [bluetooth?] BUG: sleeping function called from invalid context in hci_le_create_big_complete_evt

From: Hillf Danton
Date: Sun Apr 07 2024 - 19:14:44 EST


On Sun, 07 Apr 2024 04:33:29 -0700
> syzbot found the following issue on:
>
> HEAD commit: 480e035fc4c7 Merge tag 'drm-next-2024-03-13' of https://gi..
> git tree: upstream
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=11ee2e75180000

#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 480e035fc4c7

--- x/net/bluetooth/hci_event.c
+++ y/net/bluetooth/hci_event.c
@@ -6902,7 +6902,7 @@ static void hci_le_create_big_complete_e
struct sk_buff *skb)
{
struct hci_evt_le_create_big_complete *ev = data;
- struct hci_conn *conn;
+ struct hci_conn *conn, *next;
__u8 i = 0;

BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
@@ -6912,38 +6912,29 @@ static void hci_le_create_big_complete_e
return;

hci_dev_lock(hdev);
- rcu_read_lock();
-
/* Connect all BISes that are bound to the BIG */
- list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
+ list_for_each_entry_safe(conn, next, &hdev->conn_hash.list, list) {
if (bacmp(&conn->dst, BDADDR_ANY) ||
conn->type != ISO_LINK ||
conn->iso_qos.bcast.big != ev->handle)
continue;

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

if (!ev->status) {
conn->state = BT_CONNECTED;
set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
- rcu_read_unlock();
hci_debugfs_create_conn(conn);
hci_conn_add_sysfs(conn);
hci_iso_setup_path(conn);
- rcu_read_lock();
continue;
}

hci_connect_cfm(conn, ev->status);
- rcu_read_unlock();
hci_conn_del(conn);
- rcu_read_lock();
}

- rcu_read_unlock();
-
if (!ev->status && !i)
/* If no BISes have been connected for the BIG,
* terminate. This is in case all bound connections
@@ -6952,7 +6943,6 @@ static void hci_le_create_big_complete_e
*/
hci_cmd_sync_queue(hdev, hci_iso_term_big_sync,
UINT_PTR(ev->handle), NULL);
-
hci_dev_unlock(hdev);
}

--