Headline
CVE-2023-5753: Buffer overflow vulnerabilities in the Zephyr Bluetooth subsystem
Potential buffer overflows in the Bluetooth subsystem due to asserts being disabled in /subsys/bluetooth/host/hci_core.c
Summary
I spotted some additional buffer overflow vulnerabilities at the following locations in the Zephyr Bluetooth subsystem source code:
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/controller/ll_sw/ull_adv.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/host/hci_core.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/host/iso.c
Details
Potential integer underflow due to ineffective assert check leading to buffer overflow in /subsys/bluetooth/controller/ll_sw/ull_adv.c:
uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type, uint8_t own_addr_type, uint8_t direct_addr_type, uint8_t const *const direct_addr, uint8_t chan_map, uint8_t filter_policy) { … #if defined(CONFIG_BT_CTLR_AD_DATA_BACKUP) /* Backup the legacy AD Data if switching to legacy directed advertising * or to Extended Advertising. */ if (((pdu->type == PDU_ADV_TYPE_DIRECT_IND) || (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) && (pdu->type == PDU_ADV_TYPE_EXT_IND))) && (pdu_type_prev != PDU_ADV_TYPE_DIRECT_IND) && (!IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) || (pdu_type_prev != PDU_ADV_TYPE_EXT_IND))) { if (pdu->len == 0U) { adv->ad_data_backup.len = 0U; } else { LL_ASSERT(pdu->len >= offsetof(struct pdu_adv_adv_ind, data)); /* VULN: assert */
adv\->ad\_data\_backup.len \= pdu\->len \-
offsetof(struct pdu\_adv\_adv\_ind, data); /\* VULN: integer underflow \*/
memcpy(adv\->ad\_data\_backup.data, pdu\->adv\_ind.data,
adv\->ad\_data\_backup.len); /\* VULN: buffer overflow \*/
}
}
#endif /* CONFIG_BT_CTLR_AD_DATA_BACKUP */ …
Buffer overflows due to assert in /subsys/bluetooth/host/hci_core.c:
#if defined(CONFIG_BT_CONN) static void hci_acl(struct net_buf *buf) { struct bt_hci_acl_hdr *hdr; uint16_t handle, len; struct bt_conn *conn; uint8_t flags;
LOG\_DBG("buf %p", buf);
BT\_ASSERT(buf\->len >= sizeof(\*hdr)); /\* VULN: assert \*/
hdr \= net\_buf\_pull\_mem(buf, sizeof(\*hdr)); /\* VULN: buffer overflow \*/
len \= sys\_le16\_to\_cpu(hdr\->len);
handle \= sys\_le16\_to\_cpu(hdr\->handle);
flags \= bt\_acl\_flags(handle);
…
static void hci_event(struct net_buf *buf) { struct bt_hci_evt_hdr *hdr;
BT\_ASSERT(buf\->len >= sizeof(\*hdr)); /\* VULN: assert \*/
hdr \= net\_buf\_pull\_mem(buf, sizeof(\*hdr)); /\* VULN: buffer overflow \*/
LOG\_DBG("event 0x%02x", hdr\->evt);
BT\_ASSERT(bt\_hci\_evt\_get\_flags(hdr\->evt) & BT\_HCI\_EVT\_FLAG\_RECV);
handle\_event(hdr\->evt, buf, normal\_events, ARRAY\_SIZE(normal\_events));
net\_buf\_unref(buf);
} …
void hci_event_prio(struct net_buf *buf) { struct net_buf_simple_state state; struct bt_hci_evt_hdr *hdr; uint8_t evt_flags;
net\_buf\_simple\_save(&buf\->b, &state);
BT\_ASSERT(buf\->len >= sizeof(\*hdr)); /\* VULN: assert \*/
hdr \= net\_buf\_pull\_mem(buf, sizeof(\*hdr)); /\* VULN: buffer overflow \*/
evt\_flags \= bt\_hci\_evt\_get\_flags(hdr\->evt);
BT\_ASSERT(evt\_flags & BT\_HCI\_EVT\_FLAG\_RECV\_PRIO);
handle\_event(hdr\->evt, buf, prio\_events, ARRAY\_SIZE(prio\_events));
if (evt\_flags & BT\_HCI\_EVT\_FLAG\_RECV) {
net\_buf\_simple\_restore(&buf\->b, &state);
} else {
net\_buf\_unref(buf);
}
}
Buffer overflow due to assert in /subsys/bluetooth/host/iso.c:
void hci_iso(struct net_buf *buf) { struct bt_hci_iso_hdr *hdr; uint16_t handle, len; struct bt_conn *iso; uint8_t flags;
BT\_ISO\_DATA\_DBG("buf %p", buf);
BT\_ASSERT(buf\->len >= sizeof(\*hdr)); /\* VULN: assert \*/
hdr \= net\_buf\_pull\_mem(buf, sizeof(\*hdr)); /\* VULN: buffer overflow \*/
len \= bt\_iso\_hdr\_len(sys\_le16\_to\_cpu(hdr\->len));
handle \= sys\_le16\_to\_cpu(hdr\->handle);
flags \= bt\_iso\_flags(handle);
…
In addition, the following helper functions in /subsys/net/buf_simple.c use assertions to check input, which renders checks ineffective:
- net_buf_simple_add()
- net_buf_simple_remove_mem()
- net_buf_simple_push()
- net_buf_simple_pull()
- net_buf_simple_pull_mem()
PoC
I haven’t tried to reproduce these potential vulnerabilities against a live install of the Zephyr OS.
Impact
If the unchecked input above is attacker-controlled and crosses a security boundary, the impact of buffer overflow vulnerabilities could range from denial of service to arbitrary code execution.
Patches
This has been fixed in:
- main for 3.5: #63605
Note that the first item in this advisory, the one involving /subsys/bluetooth/controller/ll_sw/ull_adv.c, has not been addressed because the pdu length that is being asserted on has been set by the controller itself prior to the execution of this code, and so it is not coming from the outside world. Hence, an assertion is correct in that particular case.
For more information
If you have any questions or comments about this advisory:
- Open an issue in zephyr
- Email us at Zephyr-vulnerabilities
Related news
Zephyr RTOS versions 3.5.0 and below suffer from a multitude of buffer overflow vulnerabilities.