Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-4264: Buffer overflow vulnerabilities in the Zephyr Bluetooth subsystem

Potential buffer overflow vulnerabilities n the Zephyr Bluetooth subsystem.

CVE
#vulnerability#dos#git#buffer_overflow#auth

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:

  • main: #60465

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-08-19

Related news

Zephyr RTOS 3.x.0 Buffer Overflows

Zephyr RTOS versions 3.5.0 and below suffer from a multitude of buffer overflow vulnerabilities.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907