This is an automated email from the ASF dual-hosted git repository.
rymek 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 154398242 host/ble_l2cap_coc: fix possible race condition in L2CAP COC
154398242 is described below
commit 1543982424d3c5ef7d4c4dbae2203f8e3c020f18
Author: Krzysztof Kopyściński <[email protected]>
AuthorDate: Wed Apr 17 14:41:40 2024 +0200
host/ble_l2cap_coc: fix possible race condition in L2CAP COC
Two functions: `ble_l2cap_coc_continue_tx` and `ble_l2cap_coc_recv_ready`
can be reached from other task than host, for example separate thread
running in application, by calling `ble_l2cap_recv_ready` or
`ble_l2cap_send`. Because pointer to chan passed into these functions
may be outdated (connection is being terminated by host) this will lead
to either:
- triggering BLE_HS_DBG_ASSERT(conn != NULL) in ble_hs_conn_find_assert
- dereferencing NULL pointer to conn, after ble_hs_conn_find_assert
returns NULL (case with disabled BLE_HS_DEBUG)
These two cases shall not cause assert, and should be prepared for chan
not existing anymore. Now, BLE_HS_ENOTCONN is returned if connection no
longer exists.
---
nimble/host/src/ble_l2cap_coc.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c
index 25727ee19..a3d1b1c22 100644
--- a/nimble/host/src/ble_l2cap_coc.c
+++ b/nimble/host/src/ble_l2cap_coc.c
@@ -506,7 +506,12 @@ ble_l2cap_coc_continue_tx(struct ble_l2cap_chan *chan)
goto failed;
}
- conn = ble_hs_conn_find_assert(chan->conn_handle);
+ conn = ble_hs_conn_find(chan->conn_handle);
+ if (!conn) {
+ rc = BLE_HS_ENOTCONN;
+ BLE_HS_LOG(DEBUG, "Connection does not exist");
+ goto failed;
+ }
rc = ble_l2cap_tx(conn, chan, txom);
if (rc) {
@@ -619,7 +624,13 @@ ble_l2cap_coc_recv_ready(struct ble_l2cap_chan *chan,
struct os_mbuf *sdu_rx)
(chan->coc_rx.next_sdu_alloc_idx + 1) % BLE_L2CAP_SDU_BUFF_CNT;
ble_hs_lock();
- conn = ble_hs_conn_find_assert(chan->conn_handle);
+ conn = ble_hs_conn_find(chan->conn_handle);
+ if (!conn) {
+ BLE_HS_LOG(DEBUG, "Connection does not exist");
+ ble_hs_unlock();
+ return BLE_HS_ENOTCONN;
+ }
+
c = ble_hs_conn_chan_find_by_scid(conn, chan->scid);
if (!c) {
ble_hs_unlock();