Skip to content

Commit 665da0b

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 f8eaf92 commit 665da0b

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
@@ -7121,9 +7121,29 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
71217121
continue;
71227122
}
71237123

7124+
if (ev->num_bis <= i) {
7125+
bt_dev_err(hdev,
7126+
"Not enough BIS handles for BIG 0x%2.2x",
7127+
ev->handle);
7128+
ev->status = HCI_ERROR_UNSPECIFIED;
7129+
hci_connect_cfm(conn, ev->status);
7130+
hci_conn_del(conn);
7131+
continue;
7132+
}
7133+
71247134
if (hci_conn_set_handle(conn,
7125-
__le16_to_cpu(ev->bis_handle[i++])))
7135+
__le16_to_cpu(ev->bis_handle[i++]))) {
7136+
bt_dev_err(hdev,
7137+
"Failed to set BIS handle for BIG 0x%2.2x",
7138+
ev->handle);
7139+
/* Force error so BIG gets terminated as not all BIS
7140+
* could be connected.
7141+
*/
7142+
ev->status = HCI_ERROR_UNSPECIFIED;
7143+
hci_connect_cfm(conn, ev->status);
7144+
hci_conn_del(conn);
71267145
continue;
7146+
}
71277147

71287148
conn->state = BT_CONNECTED;
71297149
set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
@@ -7132,7 +7152,10 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
71327152
hci_iso_setup_path(conn);
71337153
}
71347154

7135-
if (!ev->status && !i)
7155+
/* If there is an unexpected error or if no BISes have been connected
7156+
* for the BIG, terminate it.
7157+
*/
7158+
if (ev->status == HCI_ERROR_UNSPECIFIED || (!ev->status && !i))
71367159
/* If no BISes have been connected for the BIG,
71377160
* terminate. This is in case all bound connections
71387161
* have been closed before the BIG creation

0 commit comments

Comments
 (0)