-
Notifications
You must be signed in to change notification settings - Fork 475
Closed
Description
Disclaimer: This has been created with the help of an LLM when I had crashes in my app using L2CAP channels between Apple and ESP32S3 devices.
- Environment: ESP-IDF v5.5.1 NimBLE host
- Steps to reproduce: Use CoC, receive an SDU, hand mbuf to app, later disconnect/cleanup; under load the crash occurs in os_memblock_get (os_mempool.c:360).
- Root cause: In ble_l2cap_coc_rx_fn, when an SDU completes, the pointer remains in chan->coc_rx.sdus[]. The application owns the mbuf and frees it. On disconnect, ble_l2cap_coc_cleanup_chan() frees all non-null slots again, double-freeing a block that may already be back on the free list → mempool corruption → crash.
- Fix idea: Clear the slot when handing the SDU to the app.
- Result: Prevents cleanup from freeing application-owned mbufs; resolves the os_memblock_get crash under high-rate CoC traffic.
Diff:
diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c
index 21c91ef0..fc9409f8 100644
--- a/nimble/host/src/ble_l2cap_coc.c
+++ b/nimble/host/src/ble_l2cap_coc.c
@@ -279,10 +279,10 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan)
BLE_HS_LOG(DEBUG, "Received sdu_len=%d, credits left=%d\n",
OS_MBUF_PKTLEN(rx_sdu), rx->credits);
- /* Lets get back control to os_mbuf to application.
- * Since it this callback application might want to set new sdu
- * we need to prepare space for this. Therefore we need sdu_rx
+ /* Hand off ownership of the completed SDU to the application and clear
+ * the slot so cleanup code will not attempt to free it again.
*/
+ rx->sdus[chan->coc_rx.current_sdu_idx] = NULL;
rx_sdu = NULL;
chan->coc_rx.current_sdu_idx =
(chan->coc_rx.current_sdu_idx + 1) % BLE_L2CAP_SDU_BUFF_CNT;I must confess I don't know whether this makes sense, but it fixed one of my issues, so I figured I might as well report it.
Metadata
Metadata
Assignees
Labels
No labels