Headline
CVE-2023-0396: Buffer Overreads in Bluetooth HCI
A malicious / defective bluetooth controller can cause buffer overreads in the most functions that process HCI command responses.
Summary
A malicious / defective bluetooth controller can cause buffer overreads in the most functions that process HCI command responses.
Description
Most functions that make use of bt_hci_cmd_send_sync to receive the response to a HCI command do not verify the response length is sufficient before casting to the expected response struct. This leads to buffer overreads in many places including e.g. common_init and le_init .
See for example hci_le_read_max_data_len:
struct bt_hci_rp_le_read_max_data_len *rp; struct net_buf *rsp;
bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_MAX_DATA_LEN, NULL, &rsp);
rp = (void *)rsp->data; *tx_octets = sys_le16_to_cpu(rp->max_tx_octets); *tx_time = sys_le16_to_cpu(rp->max_tx_time);
BT_HCI_OP_LE_READ_MAX_DATA_LEN defines the command opcode, rsp is the buffer containing the response data. No size check is done before the cast into bt_hci_rp_le_read_max_data_len.
Buffer size checks are done until the bt_hci_evt_cmd_complete header. This includes the required header size in coming events in hci_event_prio:
BT_ASSERT(buf->len >= sizeof(*hdr));
BT_ASSERT(buf->len >= sizeof(*hdr));
The check for the bt_hci_evt_cmd_complete header is done by handle_event_common:
if (buf->len < handler->min_len) { BT_ERR("Too small (%u bytes) event 0x%02x", buf->len, event); return -EINVAL; }
if (buf->len < handler->min_len) {
BT_ERR("Too small (%u bytes) event 0x%02x",
buf->len, event);
return -EINVAL;
}
But this does not contain a check for the expected length of the data:
// #define EVENT_HANDLER(_evt, _handler, _min_len) EVENT_HANDLER(BT_HCI_EVT_CMD_COMPLETE, hci_cmd_complete, sizeof(struct bt_hci_evt_cmd_complete)),
static const struct event_handler prio_events[] = {
EVENT_HANDLER(BT_HCI_EVT_CMD_COMPLETE, hci_cmd_complete,
sizeof(struct bt_hci_evt_cmd_complete)),
EVENT_HANDLER(BT_HCI_EVT_CMD_STATUS, hci_cmd_status,
sizeof(struct bt_hci_evt_cmd_status)),
#if defined(CONFIG_BT_CONN)
EVENT_HANDLER(BT_HCI_EVT_DATA_BUF_OVERFLOW,
hci_data_buf_overflow,
sizeof(struct bt_hci_evt_data_buf_overflow)),
EVENT_HANDLER(BT_HCI_EVT_DISCONN_COMPLETE, hci_disconn_complete_prio,
sizeof(struct bt_hci_evt_disconn_complete)),
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_CONN_TX)
EVENT_HANDLER(BT_HCI_EVT_NUM_COMPLETED_PACKETS,
hci_num_completed_packets,
sizeof(struct bt_hci_evt_num_completed_packets)),
#endif /* CONFIG_BT_CONN_TX */
};
struct bt_hci_evt_cmd_complete { uint8_t ncmd; uint16_t opcode; }
#define BT_HCI_EVT_CMD_COMPLETE 0x0e
struct bt_hci_evt_cmd_complete {
uint8_t ncmd;
uint16_t opcode;
} __packed;
Impact
- Potentially allows an attacker leak information.
- Potentially cause a Denial of Service.
Proposed Fix
- Add a mandatory min_size argument to bt_hci_cmd_send_sync similar to the handler->min_len check in handle_event_common.
- Or: Verify the buffer length on each call side of bt_hci_cmd_send_sync before casting.
Patches****For more information
If you have any questions or comments about this advisory:
- Open an issue in zephyr
- Email us at Zephyr-vulnerabilities
embargo: 2023-01-03