FAILED: patch "[PATCH] Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect()" failed to apply to 5.15-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 4d7b41c0e43995b0e992b9f8903109275744b658
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024052323-settle-unhealthy-57bc@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
4d7b41c0e439 ("Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect()")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 4d7b41c0e43995b0e992b9f8903109275744b658 Mon Sep 17 00:00:00 2001
From: Sungwoo Kim <[email protected]>
Date: Tue, 30 Apr 2024 02:32:10 -0400
Subject: [PATCH] Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Extend a critical section to prevent chan from early freeing. Also make the l2cap_connect() return type void. Nothing is using the returned value but it is ugly to return a potentially freed pointer. Making it void will help with backports because earlier kernels did use the return value. Now the compile will break for kernels where this patch is not a complete fix.
Call stack summary:
[use]l2cap_bredr_sig_cmd
l2cap_connect
┌ mutex_lock(&conn->chan_lock);
│ chan = pchan->ops->new_connection(pchan); <- alloc chan
│ __l2cap_chan_add(conn, chan);
│ l2cap_chan_hold(chan);
│ list_add(&chan->list, &conn->chan_l); ... (1)
└ mutex_unlock(&conn->chan_lock);
chan->conf_state ... (4) <- use after free[free]l2cap_conn_del
┌ mutex_lock(&conn->chan_lock); │ foreach chan in conn->chan_l: ... (2) │ l2cap_chan_put(chan); │ l2cap_chan_destroy │ kfree(chan) ... (3) <- chan freed └ mutex_unlock(&conn->chan_lock);
==================================================================
BUG: KASAN: slab-use-after-free in instrument_atomic_read include/linux/instrumented.h:68 [inline] BUG: KASAN: slab-use-after-free in _test_bit include/asm-generic/bitops/instrumented-non-atomic.h:141 [inline] BUG: KASAN: slab-use-after-free in l2cap_connect+0xa67/0x11a0 net/bluetooth/l2cap_core.c:4260 Read of size 8 at addr ffff88810bf040a0 by task kworker/u3:1/311
net/bluetooth/l2cap_core.c +10 -11
@@ -3902,13 +3902,12 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn,return 0 ; } -static struct l2cap_chan *l2cap_connect (struct l2cap_conn *conn, -struct l2cap_cmd_hdr *cmd, -u8 *data,u8 rsp_code,u8 amp_id) +static void l2cap_connect (struct l2cap_conn *conn,struct l2cap_cmd_hdr *cmd, +u8 *data,u8 rsp_code,u8 amp_id) {struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;struct l2cap_conn_rsp rsp; -struct l2cap_chan *chan =NULL , *pchan; +struct l2cap_chan *chan =NULL , *pchan =NULL ;int result, status =L2CAP_CS_NO_INFO ;u16 dcid =0 , scid =__le16_to_cpu (req->scid);
@@ -3921,7 +3920,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, &conn->hcon->dst, ACL_LINK);if (!pchan) { result =L2CAP_CR_BAD_PSM ; - goto sendresp; + goto response; }mutex_lock (&conn->chan_lock);
@@ -4008,17 +4007,15 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, } response: -l2cap_chan_unlock (pchan); -mutex_unlock (&conn->chan_lock); -l2cap_chan_put (pchan); - -sendresp: rsp.scid =cpu_to_le16 (scid); rsp.dcid =cpu_to_le16 (dcid); rsp.result =cpu_to_le16 (result); rsp.status =cpu_to_le16 (status);l2cap_send_cmd (conn, cmd->ident, rsp_code,sizeof (rsp), &rsp); +if (!pchan) +return ; +if (result ==L2CAP_CR_PEND && status ==L2CAP_CS_NO_INFO ) {struct l2cap_info_req info; info.type =cpu_to_le16 (L2CAP_IT_FEAT_MASK );
@@ -4041,7 +4038,9 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, chan->num_conf_req++; } -return chan; +l2cap_chan_unlock (pchan); +mutex_unlock (&conn->chan_lock); +l2cap_chan_put (pchan); } static int l2cap_connect_req(struct l2cap_conn *conn,