Skip to content

Commit 6cb7f67

Browse files
Vudentzgregkh
authored andcommitted
Bluetooth: hci_event: Fix OOB read and infinite loop in hci_le_create_big_complete_evt
commit 5ddb801 upstream. hci_le_create_big_complete_evt() iterates over BT_BOUND connections for a BIG handle using a while loop, accessing ev->bis_handle[i++] on each iteration. However, there is no check that i stays within ev->num_bis before the array access. When a controller sends a LE_Create_BIG_Complete event with fewer bis_handle entries than there are BT_BOUND connections for that BIG, or with num_bis=0, the loop reads beyond the valid bis_handle[] flex array into adjacent heap memory. Since the out-of-bounds values typically exceed HCI_CONN_HANDLE_MAX (0x0EFF), hci_conn_set_handle() rejects them and the connection remains in BT_BOUND state. The same connection is then found again by hci_conn_hash_lookup_big_state(), creating an infinite loop with hci_dev_lock held. Fix this by terminating the BIG if in case not all BIS could be setup properly. Fixes: a0bfde1 ("Bluetooth: ISO: Add support for connecting multiple BISes") Cc: stable@vger.kernel.org Signed-off-by: ZhiTao Ou <hkbinbinbin@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 1e1e509 commit 6cb7f67

1 file changed

Lines changed: 25 additions & 2 deletions

File tree

net/bluetooth/hci_event.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6874,9 +6874,29 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
68746874
continue;
68756875
}
68766876

6877+
if (ev->num_bis <= i) {
6878+
bt_dev_err(hdev,
6879+
"Not enough BIS handles for BIG 0x%2.2x",
6880+
ev->handle);
6881+
ev->status = HCI_ERROR_UNSPECIFIED;
6882+
hci_connect_cfm(conn, ev->status);
6883+
hci_conn_del(conn);
6884+
continue;
6885+
}
6886+
68776887
if (hci_conn_set_handle(conn,
6878-
__le16_to_cpu(ev->bis_handle[i++])))
6888+
__le16_to_cpu(ev->bis_handle[i++]))) {
6889+
bt_dev_err(hdev,
6890+
"Failed to set BIS handle for BIG 0x%2.2x",
6891+
ev->handle);
6892+
/* Force error so BIG gets terminated as not all BIS
6893+
* could be connected.
6894+
*/
6895+
ev->status = HCI_ERROR_UNSPECIFIED;
6896+
hci_connect_cfm(conn, ev->status);
6897+
hci_conn_del(conn);
68796898
continue;
6899+
}
68806900

68816901
conn->state = BT_CONNECTED;
68826902
set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
@@ -6885,7 +6905,10 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
68856905
hci_iso_setup_path(conn);
68866906
}
68876907

6888-
if (!ev->status && !i)
6908+
/* If there is an unexpected error or if no BISes have been connected
6909+
* for the BIG, terminate it.
6910+
*/
6911+
if (ev->status == HCI_ERROR_UNSPECIFIED || (!ev->status && !i))
68896912
/* If no BISes have been connected for the BIG,
68906913
* terminate. This is in case all bound connections
68916914
* have been closed before the BIG creation

0 commit comments

Comments
 (0)