@@ -2350,6 +2350,10 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
struct msghdr *msg, int len,
int count, struct sk_buff *skb)
{
+ /* `conn` may be NULL, or dangling as this is called from some contexts
+ * where `chan->ops->alloc_skb` was just called, and the connection
+ * status was not checked afterward.
+ */
struct l2cap_conn *conn = chan->conn;
struct sk_buff **frag;
int sent = 0;
@@ -2365,6 +2369,13 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
while (len) {
struct sk_buff *tmp;
+ /* Channel lock is released before requesting new skb and then
+ * reacquired thus we need to recheck channel state.
+ * chan->state == BT_CONNECTED implies that conn is still valid.
+ */
+ if (chan->state != BT_CONNECTED)
+ return -ENOTCONN;
+
count = min_t(unsigned int, conn->mtu, len);
tmp = chan->ops->alloc_skb(chan, 0, count,
the use-after-delete occurs when the bluetooth connection closes while messages are still being sent. Signed-off-by: Alexander Coffin <alex.coffin@matician.com> --- net/bluetooth/l2cap_core.c | 11 +++++++++++ 1 file changed, 11 insertions(+)