Commit 12201c62 authored by Joakim Andersson's avatar Joakim Andersson Committed by github-actions[bot]
Browse files

Bluetooth: host: Fix L2CAP sent callback on disconnected channel


When receiving the L2CAP sent callbacks the dynamic L2CAP channel may
have been disconnected already. The user of the dynamic channel should
have received the disconnected and released callbacks for this channel
to release any resources for the data being sent, so simply ignoring
this sent callback is enough.

Fix sent callbacks by providing the CID to the callback instead of a
pointer to potentially released memory, and lookup the CID to check that
it is still valid.
Signed-off-by: default avatarJoakim Andersson <joakim.andersson@nordicsemi.no>
parent dabf2375
Showing with 22 additions and 6 deletions
+22 -6
......@@ -1661,9 +1661,16 @@ static void l2cap_chan_tx_resume(struct bt_l2cap_le_chan *ch)
static void l2cap_chan_sdu_sent(struct bt_conn *conn, void *user_data)
{
struct bt_l2cap_chan *chan = user_data;
uint16_t cid = POINTER_TO_UINT(user_data);
struct bt_l2cap_chan *chan;
BT_DBG("conn %p chan %p", conn, chan);
BT_DBG("conn %p CID 0x%04x", conn, cid);
chan = bt_l2cap_le_lookup_tx_cid(conn, cid);
if (!chan) {
/* Received SDU sent callback for disconnected channel */
return;
}
if (chan->ops->sent) {
chan->ops->sent(chan);
......@@ -1674,9 +1681,16 @@ static void l2cap_chan_sdu_sent(struct bt_conn *conn, void *user_data)
static void l2cap_chan_seg_sent(struct bt_conn *conn, void *user_data)
{
struct bt_l2cap_chan *chan = user_data;
uint16_t cid = POINTER_TO_UINT(user_data);
struct bt_l2cap_chan *chan;
BT_DBG("conn %p chan %p", conn, chan);
BT_DBG("conn %p CID 0x%04x", conn, cid);
chan = bt_l2cap_le_lookup_tx_cid(conn, cid);
if (!chan) {
/* Received segment sent callback for disconnected channel */
return;
}
l2cap_chan_tx_resume(BT_L2CAP_LE_CHAN(chan));
}
......@@ -1738,10 +1752,12 @@ static int l2cap_chan_le_send(struct bt_l2cap_le_chan *ch,
*/
if ((buf == seg || !buf->len) && ch->chan.ops->sent) {
err = bt_l2cap_send_cb(ch->chan.conn, ch->tx.cid, seg,
l2cap_chan_sdu_sent, &ch->chan);
l2cap_chan_sdu_sent,
UINT_TO_POINTER(ch->tx.cid));
} else {
err = bt_l2cap_send_cb(ch->chan.conn, ch->tx.cid, seg,
l2cap_chan_seg_sent, &ch->chan);
l2cap_chan_seg_sent,
UINT_TO_POINTER(ch->tx.cid));
}
if (err) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment