esp32: Fix heap corruption triggered by bluetooth.active(0). #15538
+4
−6
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
It seems like at some point Espressif NimBLE team changed nimble_port_init and nimble_port_deinit to manage HCI init internally:
espressif/esp-nimble@f8a79b04c9743543b8959727d7
This change is now included in all the IDF versions that current 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. Setting Heap Poisoning to Comprehensive in menuconfig caused the bug to be detected every time.
Found while testing #15523.
Testing
Ran multi_bluetooth tests on ESP32 and ESP32-S3 with and without Comprehensive heap poisoning, and on IDF v5.0.4 and v5.2.2. Failures (crashes) in ble_gatt_data_transfer.py are present without this fix.