You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ja...@apache.org on 2025/12/09 07:51:41 UTC
(mynewt-nimble) branch master updated (ec622cee5 -> 70ca30a2e)
This is an automated email from the ASF dual-hosted git repository.
janc pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
from ec622cee5 nimble/host: Rework locking in L2CAP
new 9bcfd2d43 nimble/host: Drop incoming data when disconnecting L2CAP channel
new 002bdcfc7 nimble/host: Fix mbuf leak on L2CAP
new 70ca30a2e nimble/host: Fix crash on L2CAP CoC data reception
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
nimble/host/src/ble_l2cap.c | 9 +++++++
nimble/host/src/ble_l2cap_coc.c | 55 +++++++++++++++++++----------------------
2 files changed, 35 insertions(+), 29 deletions(-)
(mynewt-nimble) 03/03: nimble/host: Fix crash on L2CAP CoC data reception
Posted by ja...@apache.org.
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
commit 70ca30a2ea815ffea1195376c546fd58f0fc0835
Author: Szymon Janc <sz...@codecoup.pl>
AuthorDate: Mon Dec 8 15:46:16 2025 +0100
nimble/host: Fix crash on L2CAP CoC data reception
This fix possible double free on user provided mbuf when channel
is disconnected when data is being received.
---
nimble/host/src/ble_l2cap_coc.c | 55 +++++++++++++++++++----------------------
1 file changed, 26 insertions(+), 29 deletions(-)
diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c
index 0c38f6951..a63e50770 100644
--- a/nimble/host/src/ble_l2cap_coc.c
+++ b/nimble/host/src/ble_l2cap_coc.c
@@ -185,22 +185,19 @@ ble_l2cap_event_coc_received_data(struct ble_l2cap_chan *chan,
static int
ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan, struct os_mbuf **om)
{
- int rc;
+ struct ble_l2cap_coc_endpoint *rx = &chan->coc_rx;
struct os_mbuf *rx_sdu;
- struct ble_l2cap_coc_endpoint *rx;
+ uint16_t sdu_idx;
uint16_t om_total;
+ int rc;
- /* Create a shortcut to rx endpoint */
- rx = &chan->coc_rx;
- BLE_HS_DBG_ASSERT(rx != NULL);
-
- rx_sdu = rx->sdus[chan->coc_rx.current_sdu_idx];
- BLE_HS_DBG_ASSERT(rx_sdu != NULL);
+ sdu_idx = chan->coc_rx.current_sdu_idx;
+ BLE_HS_DBG_ASSERT(rx->sdus[sdu_idx] != NULL);
om_total = OS_MBUF_PKTLEN(*om);
/* First LE frame */
- if (OS_MBUF_PKTLEN(rx_sdu) == 0) {
+ if (OS_MBUF_PKTLEN(rx->sdus[sdu_idx]) == 0) {
uint16_t sdu_len;
rc = ble_hs_mbuf_pullup_base(om, BLE_L2CAP_SDU_SIZE);
@@ -218,7 +215,6 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan, struct os_mbuf **om)
BLE_HS_LOG(ERROR, "Payload larger than expected (%d>%d)\n",
om_total, sdu_len + 2);
/* Disconnect peer with invalid behaviour */
- rx_sdu = NULL;
rx->data_offset = 0;
ble_l2cap_disconnect(chan);
return BLE_HS_EBADDATA;
@@ -238,12 +234,13 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan, struct os_mbuf **om)
os_mbuf_adj(*om, BLE_L2CAP_SDU_SIZE);
- rc = os_mbuf_appendfrom(rx_sdu, *om, 0, om_total - BLE_L2CAP_SDU_SIZE);
+ rc = os_mbuf_appendfrom(rx->sdus[sdu_idx], *om, 0,
+ om_total - BLE_L2CAP_SDU_SIZE);
if (rc != 0) {
/* FIXME: User shall give us big enough buffer.
* need to handle it better
*/
- BLE_HS_LOG(INFO, "Could not append data rc=%d\n", rc);
+ BLE_HS_LOG(ERROR, "Could not append data rc=%d\n", rc);
assert(0);
}
@@ -253,16 +250,16 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan, struct os_mbuf **om)
} else {
BLE_HS_LOG(DEBUG, "Continuation...received %d\n", (*om)->om_len);
- if (OS_MBUF_PKTLEN(rx_sdu) + (*om)->om_len > rx->data_offset) {
+ if (OS_MBUF_PKTLEN(rx->sdus[sdu_idx]) + (*om)->om_len > rx->data_offset) {
/* Disconnect peer with invalid behaviour */
BLE_HS_LOG(ERROR, "Payload larger than expected (%d>%d)\n",
- OS_MBUF_PKTLEN(rx_sdu) + (*om)->om_len, rx->data_offset);
- rx_sdu = NULL;
+ OS_MBUF_PKTLEN(rx->sdus[sdu_idx]) + (*om)->om_len,
+ rx->data_offset);
rx->data_offset = 0;
ble_l2cap_disconnect(chan);
return BLE_HS_EBADDATA;
}
- rc = os_mbuf_appendfrom(rx_sdu, *om, 0, om_total);
+ rc = os_mbuf_appendfrom(rx->sdus[sdu_idx], *om, 0, om_total);
if (rc != 0) {
/* FIXME: need to handle it better */
BLE_HS_LOG(DEBUG, "Could not append data rc=%d\n", rc);
@@ -272,22 +269,22 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan, struct os_mbuf **om)
rx->credits--;
- if (OS_MBUF_PKTLEN(rx_sdu) == rx->data_offset) {
- struct os_mbuf *sdu_rx = rx_sdu;
-
+ if (OS_MBUF_PKTLEN(rx->sdus[sdu_idx]) == rx->data_offset) {
BLE_HS_LOG(DEBUG, "Received sdu_len=%d, credits left=%d\n",
- OS_MBUF_PKTLEN(rx_sdu), rx->credits);
+ OS_MBUF_PKTLEN(rx->sdus[sdu_idx]), 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
- */
- rx_sdu = NULL;
chan->coc_rx.current_sdu_idx =
(chan->coc_rx.current_sdu_idx + 1) % BLE_L2CAP_SDU_BUFF_CNT;
rx->data_offset = 0;
- ble_l2cap_event_coc_received_data(chan, sdu_rx);
+ /* Lets give os_mbuf control to back application.
+ * Since it this callback application might want to set new sdu
+ * we need to prepare space for this.
+ */
+ rx_sdu = rx->sdus[sdu_idx];
+ rx->sdus[sdu_idx] = NULL;
+
+ ble_l2cap_event_coc_received_data(chan, rx_sdu);
return 0;
}
@@ -305,9 +302,9 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan, struct os_mbuf **om)
ble_l2cap_sig_le_credits(chan->conn_handle, chan->scid, rx->credits);
}
- BLE_HS_LOG(DEBUG,
- "Received partial sdu_len=%d, credits left=%d, current_sdu_idx=%d\n",
- OS_MBUF_PKTLEN(rx_sdu), rx->credits, chan->coc_rx.current_sdu_idx);
+ BLE_HS_LOG(DEBUG, "Received partial sdu_len=%d, credits left=%d, current_sdu_idx=%d\n",
+ OS_MBUF_PKTLEN(rx->sdus[sdu_idx]), rx->credits,
+ chan->coc_rx.current_sdu_idx);
return 0;
}
(mynewt-nimble) 02/03: nimble/host: Fix mbuf leak on L2CAP
Posted by ja...@apache.org.
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
commit 002bdcfc7678a36307db893f4c165e4712e7d7dd
Author: Szymon Janc <sz...@codecoup.pl>
AuthorDate: Mon Dec 8 15:20:58 2025 +0100
nimble/host: Fix mbuf leak on L2CAP
Make sure to free rx data if not passing it to channel callback.
---
nimble/host/src/ble_l2cap.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c
index 584f44312..c79081eec 100644
--- a/nimble/host/src/ble_l2cap.c
+++ b/nimble/host/src/ble_l2cap.c
@@ -394,6 +394,7 @@ ble_l2cap_rx(uint16_t conn_handle, uint8_t pb, struct os_mbuf *om)
if (!chan) {
ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, 0, 0, rx_cid);
+ os_mbuf_free_chain(rx_frags);
return BLE_HS_ENOENT;
}
@@ -406,11 +407,13 @@ ble_l2cap_rx(uint16_t conn_handle, uint8_t pb, struct os_mbuf *om)
if (chan->dcid >= BLE_L2CAP_COC_CID_START &&
chan->dcid <= BLE_L2CAP_COC_CID_END && rx_len > chan->my_coc_mps) {
ble_l2cap_disconnect(chan);
+ os_mbuf_free_chain(rx_frags);
return BLE_HS_EBADDATA;
}
if (rx_len > ble_l2cap_get_mtu(chan)) {
ble_l2cap_disconnect(chan);
+ os_mbuf_free_chain(rx_frags);
return BLE_HS_EBADDATA;
}
(mynewt-nimble) 01/03: nimble/host: Drop incoming data when disconnecting L2CAP channel
Posted by ja...@apache.org.
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
commit 9bcfd2d43a752300c08def7e8702aafe852345b5
Author: Szymon Janc <sz...@codecoup.pl>
AuthorDate: Mon Dec 8 15:19:57 2025 +0100
nimble/host: Drop incoming data when disconnecting L2CAP channel
There is no point in processing data on channel that is disconnecting.
---
nimble/host/src/ble_l2cap.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c
index 69e879918..584f44312 100644
--- a/nimble/host/src/ble_l2cap.c
+++ b/nimble/host/src/ble_l2cap.c
@@ -397,6 +397,12 @@ ble_l2cap_rx(uint16_t conn_handle, uint8_t pb, struct os_mbuf *om)
return BLE_HS_ENOENT;
}
+ /* disconnect pending, drop data */
+ if (chan->flags & BLE_L2CAP_CHAN_F_DISCONNECTING) {
+ os_mbuf_free_chain(rx_frags);
+ return 0;
+ }
+
if (chan->dcid >= BLE_L2CAP_COC_CID_START &&
chan->dcid <= BLE_L2CAP_COC_CID_END && rx_len > chan->my_coc_mps) {
ble_l2cap_disconnect(chan);