This is an automated email from the ASF dual-hosted git repository.
janc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
The following commit(s) were added to refs/heads/master by this push:
new 55c2d46e6 nimble/host: Fix race in HCI ACL TX outstanding packets
counter
55c2d46e6 is described below
commit 55c2d46e644cf9124ef382c93559ac016337cc39
Author: Deomid rojer Ryabkov <[email protected]>
AuthorDate: Wed Apr 1 00:51:41 2026 +0300
nimble/host: Fix race in HCI ACL TX outstanding packets counter
The outstanding packets counter (bhc_outstanding_pkts / avail_pkts)
was decremented after ble_hs_tx_data() returned. However, by that
point the controller may have already processed the packet and sent
a Number of Completed Packets event, which increments avail_pkts.
This race can cause avail_pkts to momentarily exceed the controller
maximum, leading to buffer overflows.
Move the counter update before ble_hs_tx_data() and roll back on
error.
Forward-port of https://github.com/espressif/esp-nimble/commit/f5136d2b3
---
nimble/host/src/ble_hs_hci.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/nimble/host/src/ble_hs_hci.c b/nimble/host/src/ble_hs_hci.c
index e53e4b73b..6f9c4687b 100644
--- a/nimble/host/src/ble_hs_hci.c
+++ b/nimble/host/src/ble_hs_hci.c
@@ -560,8 +560,17 @@ ble_hs_hci_acl_tx_now(struct ble_hs_conn *conn, struct
os_mbuf **om)
BLE_HS_LOG(DEBUG, "\n");
#endif
+ /* Account for the controller buf that will hold the txed fragment.
+ * Do this before ble_hs_tx_data() to avoid a race with the Number of
+ * Completed Packets event that may arrive before tx returns.
+ */
+ conn->bhc_outstanding_pkts++;
+ ble_hs_hci_avail_pkts--;
+
rc = ble_hs_tx_data(frag);
if (rc != 0) {
+ conn->bhc_outstanding_pkts--;
+ ble_hs_hci_avail_pkts++;
goto err;
}
@@ -570,10 +579,6 @@ ble_hs_hci_acl_tx_now(struct ble_hs_conn *conn, struct
os_mbuf **om)
*/
conn->bhc_flags |= BLE_HS_CONN_F_TX_FRAG;
pb = BLE_HCI_PB_MIDDLE;
-
- /* Account for the controller buf that will hold the txed fragment. */
- conn->bhc_outstanding_pkts++;
- ble_hs_hci_avail_pkts--;
}
if (txom != NULL) {