From 1754c587f9375f35c73d83982396b4f5232566ce Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 25 Jul 2024 11:57:09 +1000 Subject: [PATCH] esp32: Fix heap corruption triggered by bluetooth.active(0). It seems like at some point Espressif NimBLE team changed nimble_port_init and nimble_port_deinit to manage HCI init internally: https://github.com/espressif/esp-nimble/commit/f8a79b04c9743543b8959727d7 This change is included in all the IDF versions that MicroPython supports. As a result, existing code that called esp_nimble_hci_deinit() explicitly would trigger a use-after-free bug and heap corruption (specifically this calls through to ble_transport_deinit() which calls os_mempool_free(). The second time this writes out to a bunch of memory pools where the backing buffers have already been freed.) Symptoms were intermittent random crashes after de-activating Bluetooth (running multi_bluetooth/ble_gatt_data_transfer.py could sometimes reproduce). Setting Heap Poisoning to Comprehensive in menuconfig caused the bug to be detected every time. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- ports/esp32/mpnimbleport.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/ports/esp32/mpnimbleport.c b/ports/esp32/mpnimbleport.c index 669aeb746a..ce4b77727a 100644 --- a/ports/esp32/mpnimbleport.c +++ b/ports/esp32/mpnimbleport.c @@ -32,7 +32,6 @@ #define DEBUG_printf(...) // printf("nimble (esp32): " __VA_ARGS__) -#include "esp_nimble_hci.h" #include "nimble/nimble_port.h" #include "nimble/nimble_port_freertos.h" @@ -45,14 +44,13 @@ static void ble_host_task(void *param) { } void mp_bluetooth_nimble_port_hci_init(void) { - DEBUG_printf("mp_bluetooth_nimble_port_hci_init\n"); - esp_nimble_hci_init(); + // On ESP-IDF the standard nimble_port_init() function calls + // esp_nimble_init() which initialises the HCI } void mp_bluetooth_nimble_port_hci_deinit(void) { - DEBUG_printf("mp_bluetooth_nimble_port_hci_deinit\n"); - - esp_nimble_hci_deinit(); + // As above, this is handled by ESP-IDF nimble_port_deinit() + // (called below) } void mp_bluetooth_nimble_port_start(void) {