From 466d450b4bda313775fef19311e896be2e5e5983 Mon Sep 17 00:00:00 2001 From: lly Date: Wed, 1 Apr 2020 20:02:10 +0800 Subject: [PATCH] ble_mesh: Add length check for some mesh operations --- .../core/esp_ble_mesh_local_data_operation_api.c | 3 +++ .../api/core/esp_ble_mesh_provisioning_api.c | 12 +++++++++--- .../bt/esp_ble_mesh/api/esp_ble_mesh_defs.h | 9 +++++++++ .../bt/esp_ble_mesh/mesh_core/include/mesh_main.h | 4 ++++ components/bt/esp_ble_mesh/mesh_core/prov.c | 7 +++++++ .../bt/esp_ble_mesh/mesh_core/provisioner_prov.c | 5 +++++ .../bt/esp_ble_mesh/mesh_core/proxy_client.c | 5 +++++ .../components/esp_fast_prov_server_model.c | 15 ++++++--------- 8 files changed, 48 insertions(+), 12 deletions(-) diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c index 656cae4f0..5d86dda5a 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c @@ -44,6 +44,9 @@ uint16_t *esp_ble_mesh_is_model_subscribed_to_group(esp_ble_mesh_model_t *model, esp_ble_mesh_elem_t *esp_ble_mesh_find_element(uint16_t element_addr) { + if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr)) { + return NULL; + } return btc_ble_mesh_elem_find(element_addr); } diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c index d4d321d2a..b1f19cb91 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c @@ -118,7 +118,7 @@ esp_err_t esp_ble_mesh_node_input_string(const char *string) btc_ble_mesh_prov_args_t arg = {0}; btc_msg_t msg = {0}; - if (!string) { + if (!string || strlen(string) > ESP_BLE_MESH_PROV_INPUT_OOB_MAX_LEN) { return ESP_ERR_INVALID_ARG; } @@ -187,7 +187,8 @@ esp_err_t esp_ble_mesh_provisioner_input_string(const char *string, uint8_t link btc_ble_mesh_prov_args_t arg = {0}; btc_msg_t msg = {0}; - if (!string || link_idx >= MAX_PROV_LINK_IDX) { + if (!string || strlen(string) > ESP_BLE_MESH_PROV_OUTPUT_OOB_MAX_LEN || + link_idx >= MAX_PROV_LINK_IDX) { return ESP_ERR_INVALID_ARG; } @@ -353,6 +354,10 @@ esp_err_t esp_ble_mesh_provisioner_set_dev_uuid_match(const uint8_t *match_val, btc_ble_mesh_prov_args_t arg = {0}; btc_msg_t msg = {0}; + if (match_len + offset > ESP_BLE_MESH_OCTET16_LEN) { + return ESP_ERR_INVALID_ARG; + } + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; @@ -449,7 +454,8 @@ esp_err_t esp_ble_mesh_set_fast_prov_info(esp_ble_mesh_fast_prov_info_t *fast_pr btc_ble_mesh_prov_args_t arg = {0}; btc_msg_t msg = {0}; - if (fast_prov_info == NULL) { + if (fast_prov_info == NULL || (fast_prov_info->offset + + fast_prov_info->match_len > ESP_BLE_MESH_OCTET16_LEN)) { return ESP_ERR_INVALID_ARG; } diff --git a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h index 753697d2d..acc8a818e 100644 --- a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h +++ b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h @@ -242,6 +242,15 @@ typedef enum { ESP_BLE_MESH_PROV_OOB_ON_DEV = BIT(15), } esp_ble_mesh_prov_oob_info_t; +/*!< Maximum length of value used by Static OOB authentication */ +#define ESP_BLE_MESH_PROV_STATIC_OOB_MAX_LEN 16 + +/*!< Maximum length of string used by Output OOB authentication */ +#define ESP_BLE_MESH_PROV_OUTPUT_OOB_MAX_LEN 8 + +/*!< Maximum length of string used by Output OOB authentication */ +#define ESP_BLE_MESH_PROV_INPUT_OOB_MAX_LEN 8 + /*!< Macros used to define message opcode */ #define ESP_BLE_MESH_MODEL_OP_1(b0) (b0) #define ESP_BLE_MESH_MODEL_OP_2(b0, b1) (((b0) << 8) | (b1)) diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h index eb5cc5533..672d9817c 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h @@ -62,6 +62,10 @@ typedef enum { BLE_MESH_PROV_OOB_ON_DEV = BIT(15), } bt_mesh_prov_oob_info_t; +#define BLE_MESH_PROV_STATIC_OOB_MAX_LEN 16 +#define BLE_MESH_PROV_OUTPUT_OOB_MAX_LEN 8 +#define BLE_MESH_PROV_INPUT_OOB_MAX_LEN 8 + /** Provisioning properties & capabilities. */ struct bt_mesh_prov { #if CONFIG_BLE_MESH_NODE diff --git a/components/bt/esp_ble_mesh/mesh_core/prov.c b/components/bt/esp_ble_mesh/mesh_core/prov.c index 6f95087c0..bc36a6efb 100644 --- a/components/bt/esp_ble_mesh/mesh_core/prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/prov.c @@ -1743,6 +1743,13 @@ int bt_mesh_prov_init(const struct bt_mesh_prov *prov_info) return -EINVAL; } + if (prov_info->static_val_len > BLE_MESH_PROV_STATIC_OOB_MAX_LEN || + prov_info->output_size > BLE_MESH_PROV_OUTPUT_OOB_MAX_LEN || + prov_info->input_size > BLE_MESH_PROV_INPUT_OOB_MAX_LEN) { + BT_ERR("%s, Invalid auth oob length", __func__); + return -EINVAL; + } + /* Changed by Espressif. Use micro-ecc to generate public key now. */ key = bt_mesh_pub_key_get(); if (!key) { diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c index 7c930965b..1a1870750 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c @@ -2178,6 +2178,11 @@ int bt_mesh_provisioner_set_oob_output_data(const u8_t idx, const u8_t *num, u8_ * Parameter num_flag is used to indicate whether the value * output by provisioner is number or string. */ + if (num == NULL || size > BLE_MESH_PROV_INPUT_OOB_MAX_LEN) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + if (!link[idx].auth) { BT_ERR("%s, link auth is NULL", __func__); return -EINVAL; diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_client.c b/components/bt/esp_ble_mesh/mesh_core/proxy_client.c index fc3472667..784eed645 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_client.c +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_client.c @@ -660,6 +660,11 @@ void bt_mesh_proxy_client_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh switch (type) { case BLE_MESH_PROXY_ADV_NET_ID: { + if (buf->len != sizeof(ctx.net_id.net_id)) { + BT_WARN("Malformed Network ID"); + return; + } + struct bt_mesh_subnet *sub = NULL; sub = bt_mesh_is_net_id_exist(buf->data); if (!sub) { diff --git a/examples/bluetooth/esp_ble_mesh/common_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.c b/examples/bluetooth/esp_ble_mesh/common_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.c index d5dd42c0a..9168aeab3 100644 --- a/examples/bluetooth/esp_ble_mesh/common_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.c +++ b/examples/bluetooth/esp_ble_mesh/common_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.c @@ -139,7 +139,7 @@ esp_err_t example_fast_prov_server_recv_msg(esp_ble_mesh_model_t *model, * status_bit_mask (2) + status_ctx_flag (1) + status_unicast (1) + status_net_idx (1) + * status_group (1) + status_pri_prov (1) + status_match (1) + status_action (1). */ - uint8_t match_len = 0, match_val[16]; + uint8_t match_len = 0, match_val[16] = {0}; uint8_t status_unicast = 0; uint8_t flags = 0; @@ -186,6 +186,11 @@ esp_err_t example_fast_prov_server_recv_msg(esp_ble_mesh_model_t *model, uint16_t pri_prov_addr = (ctx_flags & BIT(7)) ? net_buf_simple_pull_le16(buf) : ESP_BLE_MESH_ADDR_UNASSIGNED; if (ctx_flags & BIT(8)) { match_len = buf->len - ((ctx_flags & BIT(9)) ? 1 : 0); + if (match_len > ESP_BLE_MESH_OCTET16_LEN) { + net_buf_simple_add_le16(msg, BIT(5)); + net_buf_simple_add_u8(msg, 0x01); /* too large match value length */ + break; + } memcpy(match_val, buf->data, match_len); net_buf_simple_pull(buf, match_len); } @@ -249,14 +254,6 @@ esp_err_t example_fast_prov_server_recv_msg(esp_ble_mesh_model_t *model, } } - if (ctx_flags & BIT(8)) { - if (match_len > 16) { - net_buf_simple_add_le16(msg, BIT(5)); - net_buf_simple_add_u8(msg, 0x01); /* too large match value length */ - break; - } - } - if (ctx_flags & BIT(9)) { if ((action & BIT_MASK(2)) != FAST_PROV_ACT_ENTER) { net_buf_simple_add_le16(msg, BIT(6));