fix(nimble): Fix vulnerabilities in NimBLE examples

This commit is contained in:
Shreeyash
2026-03-10 14:46:05 +05:30
parent 5ecafbffc1
commit ea1a30b3ef
43 changed files with 875 additions and 303 deletions
@@ -23,6 +23,7 @@ static int ble_spp_client_gap_event(struct ble_gap_event *event, void *arg);
QueueHandle_t spp_common_uart_queue = NULL;
void ble_store_config_init(void);
uint16_t attribute_handle[CONFIG_BT_NIMBLE_MAX_CONNECTIONS + 1];
static SemaphoreHandle_t g_attr_handle_mutex = NULL;
static void ble_spp_client_scan(void);
static ble_addr_t connected_addr[CONFIG_BT_NIMBLE_MAX_CONNECTIONS + 1];
@@ -73,8 +74,19 @@ ble_spp_client_set_handle(const struct peer *peer)
chr = peer_chr_find_uuid(peer,
BLE_UUID16_DECLARE(GATT_SPP_SVC_UUID),
BLE_UUID16_DECLARE(GATT_SPP_CHR_UUID));
if (chr == NULL) {
MODLOG_DFLT(ERROR, "Error: Peer lacks SPP characteristic\n");
return;
}
if (g_attr_handle_mutex != NULL) {
xSemaphoreTake(g_attr_handle_mutex, portMAX_DELAY);
}
attribute_handle[peer->conn_handle] = chr->chr.val_handle;
MODLOG_DFLT(INFO, "attribute_handle %x\n", attribute_handle[peer->conn_handle]);
if (g_attr_handle_mutex != NULL) {
xSemaphoreGive(g_attr_handle_mutex);
}
dsc = peer_dsc_find_uuid(peer,
BLE_UUID16_DECLARE(GATT_SPP_SVC_UUID),
@@ -295,8 +307,10 @@ ble_spp_client_gap_event(struct ble_gap_event *event, void *arg)
MODLOG_DFLT(INFO, "Connection established ");
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
assert(rc == 0);
memcpy(&connected_addr[event->connect.conn_handle].val, desc.peer_id_addr.val,
PEER_ADDR_VAL_SIZE);
if (event->connect.conn_handle <= CONFIG_BT_NIMBLE_MAX_CONNECTIONS) {
memcpy(&connected_addr[event->connect.conn_handle].val, desc.peer_id_addr.val,
PEER_ADDR_VAL_SIZE);
}
print_conn_desc(&desc);
MODLOG_DFLT(INFO, "\n");
@@ -333,7 +347,13 @@ ble_spp_client_gap_event(struct ble_gap_event *event, void *arg)
/* Forget about peer. */
memset(&connected_addr[event->disconnect.conn.conn_handle].val, 0, PEER_ADDR_VAL_SIZE);
if (g_attr_handle_mutex != NULL) {
xSemaphoreTake(g_attr_handle_mutex, portMAX_DELAY);
}
attribute_handle[event->disconnect.conn.conn_handle] = 0;
if (g_attr_handle_mutex != NULL) {
xSemaphoreGive(g_attr_handle_mutex);
}
peer_delete(event->disconnect.conn.conn_handle);
/* Resume scanning. */
@@ -422,19 +442,39 @@ void ble_client_uart_task(void *pvParameters)
}
memset(temp, 0x0, event.size);
uart_read_bytes(UART_NUM_0, temp, event.size, portMAX_DELAY);
for ( i = 0; i <= CONFIG_BT_NIMBLE_MAX_CONNECTIONS; i++) {
/* Collect valid connections while holding mutex to prevent race conditions */
struct {
uint16_t conn_handle;
uint16_t attr_handle;
} valid_conns[CONFIG_BT_NIMBLE_MAX_CONNECTIONS + 1];
int valid_count = 0;
if (g_attr_handle_mutex != NULL) {
xSemaphoreTake(g_attr_handle_mutex, portMAX_DELAY);
}
for (i = 0; i <= CONFIG_BT_NIMBLE_MAX_CONNECTIONS; i++) {
if (attribute_handle[i] != 0) {
#if MYNEWT_VAL(BLE_GATTC)
rc = ble_gattc_write_flat(i, attribute_handle[i], temp, event.size, NULL, NULL);
if (rc == 0) {
ESP_LOGI(tag, "Write in uart task success!");
} else {
ESP_LOGI(tag, "Error in writing characteristic rc=%d", rc);
}
#endif
vTaskDelay(10);
valid_conns[valid_count].conn_handle = i;
valid_conns[valid_count].attr_handle = attribute_handle[i];
valid_count++;
}
}
if (g_attr_handle_mutex != NULL) {
xSemaphoreGive(g_attr_handle_mutex);
}
/* Write to all valid connections (outside mutex to avoid blocking) */
for (i = 0; i < valid_count; i++) {
#if MYNEWT_VAL(BLE_GATTC)
rc = ble_gattc_write_flat(valid_conns[i].conn_handle, valid_conns[i].attr_handle, temp, event.size, NULL, NULL);
if (rc == 0) {
ESP_LOGI(tag, "Write in uart task success!");
} else {
ESP_LOGI(tag, "Error in writing characteristic rc=%d", rc);
}
#endif
vTaskDelay(10);
}
free(temp);
}
break;
@@ -484,6 +524,13 @@ app_main(void)
return;
}
/* Initialize mutex for attribute_handle protection */
g_attr_handle_mutex = xSemaphoreCreateMutex();
if (g_attr_handle_mutex == NULL) {
ESP_LOGE(tag, "Failed to create attribute handle mutex");
return;
}
/* Initialize UART driver and start uart task */
ble_spp_uart_init();
@@ -163,7 +163,9 @@ ble_spp_server_gap_event(struct ble_gap_event *event, void *arg)
ble_spp_server_print_conn_desc(&event->disconnect.conn);
MODLOG_DFLT(INFO, "\n");
conn_handle_subs[event->disconnect.conn.conn_handle] = false;
if (event->disconnect.conn.conn_handle <= CONFIG_BT_NIMBLE_MAX_CONNECTIONS) {
conn_handle_subs[event->disconnect.conn.conn_handle] = false;
}
/* Connection terminated; resume advertising. */
ble_spp_server_advertise();
@@ -202,7 +204,9 @@ ble_spp_server_gap_event(struct ble_gap_event *event, void *arg)
event->subscribe.cur_notify,
event->subscribe.prev_indicate,
event->subscribe.cur_indicate);
conn_handle_subs[event->subscribe.conn_handle] = true;
if (event->subscribe.conn_handle <= CONFIG_BT_NIMBLE_MAX_CONNECTIONS) {
conn_handle_subs[event->subscribe.conn_handle] = true;
}
return 0;
default:
@@ -360,6 +364,10 @@ void ble_server_uart_task(void *pvParameters)
if (event.size) {
uint8_t *ntf;
ntf = (uint8_t *)malloc(sizeof(uint8_t) * event.size);
if (ntf == NULL) {
MODLOG_DFLT(ERROR, "malloc failed for UART data, size=%u", event.size);
continue;
}
memset(ntf, 0x00, event.size);
uart_read_bytes(UART_NUM_0, ntf, event.size, portMAX_DELAY);