Headline
CVE-2023-0397: DoS: Invalid Initialization in `le_read_buffer_size_complete`
A malicious / defect bluetooth controller can cause a Denial of Service due to unchecked input in le_read_buffer_size_complete.
Summary
A malicious / defect bluetooth controller can cause a Denial of Service due to unchecked input in le_read_buffer_size_complete.
Description
LE Buffer Size is requested from bluehtooh controller and passed into le_read_buffer_size_complete without further checks:
bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_BUFFER_SIZE, NULL, &rsp); le_read_buffer_size_complete(rsp);
/* Read LE Buffer Size */
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_BUFFER_SIZE,
NULL, &rsp);
if (err) {
return err;
}
le_read_buffer_size_complete(rsp);
le_read_buffer_size_complete casts the response into a bt_hci_rp_le_read_buffer_size struct but only checks that le_max_len is set:
static void le_read_buffer_size_complete(struct net_buf *buf) { struct bt_hci_rp_le_read_buffer_size *rp = (void *)buf->data; bt_dev.le.acl_mtu = sys_le16_to_cpu(rp->le_max_len); if (!bt_dev.le.acl_mtu) { return; }
struct bt_hci_rp_le_read_buffer_size *rp = (void *)buf->data;
BT_DBG("status 0x%02x", rp->status);
#if defined(CONFIG_BT_CONN)
bt_dev.le.acl_mtu = sys_le16_to_cpu(rp->le_max_len);
if (!bt_dev.le.acl_mtu) {
return;
}
it passes the unchecked rp->le_max_num into k_sem_init:
k_sem_init(&bt_dev.le.acl_pkts, rp->le_max_num, rp->le_max_num);
k_sem_init(&bt_dev.le.acl_pkts, rp->le_max_num, rp->le_max_num);
However k_sem_init requires the limit to be greater than zero or skips the initialization otherwise:
int z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count, unsigned int limit) { CHECKIF(limit == 0U || limit > K_SEM_MAX_LIMIT || initial_count > limit) { return -EINVAL; }
int z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count,
unsigned int limit)
{
/*
* Limit cannot be zero and count cannot be greater than limit
*/
CHECKIF(limit == 0U || limit > K_SEM_MAX_LIMIT || initial_count > limit) {
SYS_PORT_TRACING_OBJ_FUNC(k_sem, init, sem, -EINVAL);
return -EINVAL;
}
This ultimately leads to a nullptr-deref when the wait_q of the semaphore is used in z_impl_k_sem_take.
Impact
- Denial of Service
Proposed Fix
- Verify rp->le_max_num is a valid value in le_read_buffer_size_complete
- Either return an error if not or use max(1, rp->le_max_num)
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