Skip to content

Commit 22559ad

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 c411cf1 commit 22559ad

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
@@ -6935,9 +6935,29 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
69356935
continue;
69366936
}
69376937

6938+
if (ev->num_bis <= i) {
6939+
bt_dev_err(hdev,
6940+
"Not enough BIS handles for BIG 0x%2.2x",
6941+
ev->handle);
6942+
ev->status = HCI_ERROR_UNSPECIFIED;
6943+
hci_connect_cfm(conn, ev->status);
6944+
hci_conn_del(conn);
6945+
continue;
6946+
}
6947+
69386948
if (hci_conn_set_handle(conn,
6939-
__le16_to_cpu(ev->bis_handle[i++])))
6949+
__le16_to_cpu(ev->bis_handle[i++]))) {
6950+
bt_dev_err(hdev,
6951+
"Failed to set BIS handle for BIG 0x%2.2x",
6952+
ev->handle);
6953+
/* Force error so BIG gets terminated as not all BIS
6954+
* could be connected.
6955+
*/
6956+
ev->status = HCI_ERROR_UNSPECIFIED;
6957+
hci_connect_cfm(conn, ev->status);
6958+
hci_conn_del(conn);
69406959
continue;
6960+
}
69416961

69426962
conn->state = BT_CONNECTED;
69436963
set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
@@ -6946,7 +6966,10 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
69466966
hci_iso_setup_path(conn);
69476967
}
69486968

6949-
if (!ev->status && !i)
6969+
/* If there is an unexpected error or if no BISes have been connected
6970+
* for the BIG, terminate it.
6971+
*/
6972+
if (ev->status == HCI_ERROR_UNSPECIFIED || (!ev->status && !i))
69506973
/* If no BISes have been connected for the BIG,
69516974
* terminate. This is in case all bound connections
69526975
* have been closed before the BIG creation

0 commit comments

Comments
 (0)