Summary
I spotted a few buffer overflow vulnerabilities at the following locations in the Zephyr Bluetooth subsystem source code:
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/audio/tbs.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/audio/shell/mcc.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/audio/shell/media_controller.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/host/conn.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/mesh/beacon.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/mesh/prov_device.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/mesh/provisioner.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/mesh/shell/rpr.c
Details
Static buffer overflows in /subsys/bluetooth/audio/tbs.c:
int bt_tbs_remote_incoming(uint8_t bearer_index, const char *to,
const char *from, const char *friendly_name)
{
struct tbs_service_inst *inst;
struct bt_tbs_call *call = NULL;
size_t local_uri_ind_len;
size_t remote_uri_ind_len;
size_t friend_name_ind_len;
...
inst = &svc_insts[bearer_index];
...
if (friendly_name) {
inst->friendly_name.call_index = call->index;
(void)strcpy(inst->friendly_name.uri, friendly_name); /* VULN */
friend_name_ind_len = strlen(from) + 1;
...
if (IS_ENABLED(CONFIG_BT_GTBS)) {
...
if (friendly_name) {
gtbs_inst.friendly_name.call_index = call->index;
(void)strcpy(gtbs_inst.friendly_name.uri, friendly_name); /* VULN */
friend_name_ind_len = strlen(from) + 1;
...
Stack-based buffer overflow in /subsys/bluetooth/audio/shell/mcc.c:
#ifdef CONFIG_BT_MCC_OTS
static int cmd_mcc_send_search_raw(const struct shell *sh, size_t argc,
char *argv[])
{
int result;
struct mpl_search search;
search.len = strlen(argv[1]);
memcpy(search.search, argv[1], search.len); /* VULN */
LOG_DBG("Search string: %s", argv[1]);
result = bt_mcc_send_search(default_conn, &search);
if (result) {
shell_print(sh, "Fail: %d", result);
}
return result;
}
Stack-based buffer overflow in /subsys/bluetooth/audio/shell/media_controller.c:
#ifdef CONFIG_BT_OTS
static int cmd_media_set_search(const struct shell *sh, size_t argc, char *argv[])
{
/* TODO: Currently takes the raw search as input - add parameters
* and build the search item here
*/
struct mpl_search search;
int err;
search.len = strlen(argv[1]);
memcpy(search.search, argv[1], search.len); /* VULN */
LOG_DBG("Search string: %s", argv[1]);
err = media_proxy_ctrl_send_search(current_player, &search);
if (err) {
shell_error(ctx_shell, "Search send failed (%d)", err);
}
return err;
}
Heap-based buffer overflow in /subsys/bluetooth/host/conn.c:
#if defined(CONFIG_BT_SMP)
...
int bt_conn_le_start_encryption(struct bt_conn *conn, uint8_t rand[8],
uint8_t ediv[2], const uint8_t *ltk, size_t len)
{
struct bt_hci_cp_le_start_encryption *cp;
struct net_buf *buf;
buf = bt_hci_cmd_create(BT_HCI_OP_LE_START_ENCRYPTION, sizeof(*cp));
if (!buf) {
return -ENOBUFS;
}
cp = net_buf_add(buf, sizeof(*cp));
cp->handle = sys_cpu_to_le16(conn->handle);
memcpy(&cp->rand, rand, sizeof(cp->rand));
memcpy(&cp->ediv, ediv, sizeof(cp->ediv));
memcpy(cp->ltk, ltk, len); /* VULN */
if (len < sizeof(cp->ltk)) {
(void)memset(cp->ltk + len, 0, sizeof(cp->ltk) - len);
}
return bt_hci_cmd_send_sync(BT_HCI_OP_LE_START_ENCRYPTION, buf, NULL);
}
Ineffective size check due to assert and buffer overflow in /subsys/bluetooth/mesh/beacon.c:
void bt_mesh_beacon_priv_random_get(uint8_t *random, size_t size)
{
__ASSERT(size <= sizeof(priv_random.val), "Invalid random value size %u", size);
memcpy(random, priv_random.val, size); /* VULN */
}
Static buffer overflow in /subsys/bluetooth/mesh/prov_device.c (conf_size could be 32 and not 16):
static void prov_confirm(const uint8_t *data)
{
uint8_t conf_size = bt_mesh_prov_auth_size_get();
LOG_DBG("Remote Confirm: %s", bt_hex(data, conf_size));
memcpy(bt_mesh_prov_link.conf, data, conf_size); /* VULN */
notify_input_complete();
send_confirm();
}
Static buffer overflow in /subsys/bluetooth/mesh/provisioner.c (conf_size could be 32 and not 16):
static void prov_confirm(const uint8_t *data)
{
uint8_t conf_size = bt_mesh_prov_auth_size_get();
LOG_DBG("Remote Confirm: %s", bt_hex(data, conf_size));
if (!memcmp(data, bt_mesh_prov_link.conf, conf_size)) {
LOG_ERR("Confirm value is identical to ours, rejecting.");
prov_fail(PROV_ERR_CFM_FAILED);
return;
}
memcpy(bt_mesh_prov_link.conf, data, conf_size); /* VULN */
send_random();
}
Stack-based buffer overflow in /subsys/bluetooth/mesh/shell/rpr.c:
static void rpr_scan_report(struct bt_mesh_rpr_cli *cli,
const struct bt_mesh_rpr_node *srv,
struct bt_mesh_rpr_unprov *unprov,
struct net_buf_simple *adv_data)
{
char uuid_hex_str[32 + 1];
bin2hex(unprov->uuid, 16, uuid_hex_str, sizeof(uuid_hex_str));
shell_print(bt_mesh_shell_ctx_shell,
"Server 0x%04x:\n"
"\tuuid: %s\n"
"\tOOB: 0x%04x",
srv->addr, uuid_hex_str, unprov->oob);
while (adv_data && adv_data->len > 2) {
uint8_t len, type;
uint8_t data[31];
len = net_buf_simple_pull_u8(adv_data) - 1;
type = net_buf_simple_pull_u8(adv_data);
memcpy(data, net_buf_simple_pull_mem(adv_data, len), len); /* VULN */
data[len] = '\0';
if (type == BT_DATA_URI) {
shell_print(bt_mesh_shell_ctx_shell, "\tURI: \"\\x%02x%s\"",
data[0], &data[1]);
} else if (type == BT_DATA_NAME_COMPLETE) {
shell_print(bt_mesh_shell_ctx_shell, "\tName: \"%s\"", data);
} else {
char string[64 + 1];
bin2hex(data, len, string, sizeof(string));
shell_print(bt_mesh_shell_ctx_shell, "\t0x%02x: %s", type, string);
}
}
}
PoC
I haven't tried to reproduce these potential vulnerabilities against a live install of the Zephyr OS.
Impact
If the unchecked inputs above are attacker-controlled and cross a security boundary, the impact of the buffer overflow vulnerabilities could range from denial of service to arbitrary code execution.
Patches
This has been fixed in:
For more information
If you have any questions or comments about this advisory:
embargo: 2023-08-19
Summary
I spotted a few buffer overflow vulnerabilities at the following locations in the Zephyr Bluetooth subsystem source code:
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/audio/tbs.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/audio/shell/mcc.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/audio/shell/media_controller.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/host/conn.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/mesh/beacon.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/mesh/prov_device.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/mesh/provisioner.c
https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/bluetooth/mesh/shell/rpr.c
Details
Static buffer overflows in /subsys/bluetooth/audio/tbs.c:
Stack-based buffer overflow in /subsys/bluetooth/audio/shell/mcc.c:
Stack-based buffer overflow in /subsys/bluetooth/audio/shell/media_controller.c:
Heap-based buffer overflow in /subsys/bluetooth/host/conn.c:
Ineffective size check due to assert and buffer overflow in /subsys/bluetooth/mesh/beacon.c:
Static buffer overflow in /subsys/bluetooth/mesh/prov_device.c (conf_size could be 32 and not 16):
Static buffer overflow in /subsys/bluetooth/mesh/provisioner.c (conf_size could be 32 and not 16):
Stack-based buffer overflow in /subsys/bluetooth/mesh/shell/rpr.c:
PoC
I haven't tried to reproduce these potential vulnerabilities against a live install of the Zephyr OS.
Impact
If the unchecked inputs above are attacker-controlled and cross a security boundary, the impact of the buffer overflow vulnerabilities could range from denial of service to arbitrary code execution.
Patches
This has been fixed in:
#58834
#60465
#61845
For more information
If you have any questions or comments about this advisory:
embargo: 2023-08-19