All of lore.kernel.org
 help / color / mirror / Atom feed
* FAILED: patch "[PATCH] Bluetooth: mgmt: fix race in read_unconf_index_list()" failed to apply to 5.15-stable tree
@ 2026-09-29 11:49 gregkh
  2026-09-30 18:28 ` [PATCH 5.15.y 1/3] Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect() Sasha Levin
  0 siblings, 1 reply; 4+ messages in thread
From: gregkh @ 2026-09-29 11:49 UTC (permalink / raw)
  To: qwe.aldo, luiz.von.dentz; +Cc: stable


The 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 <stable@vger.kernel.org>.

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 b5dbb41b212c50c095a4dbee3017a84fe94f033b
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026092958-cathouse-visiting-7f57@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'

Possible dependencies:



thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From b5dbb41b212c50c095a4dbee3017a84fe94f033b Mon Sep 17 00:00:00 2001
From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Date: Tue, 15 Sep 2026 12:59:52 -0300
Subject: [PATCH] Bluetooth: mgmt: fix race in read_unconf_index_list()

read_unconf_index_list() counts unconfigured controllers before allocating
its response, then checks the device flags again while filling it.

hci_dev_list_lock stabilizes list membership, but it does not serialize the
per-device flags. During asynchronous controller setup, the worker can set
HCI_UNCONFIGURED and clear HCI_SETUP between the two passes. A controller
omitted from the allocation count can then become eligible for the fill
pass, causing an out-of-bounds write to rp->index[].

Allocate space for every device on hci_dev_list. Since list membership
cannot change while hci_dev_list_lock is held, the response remains large
enough regardless of flag transitions. The reported count and response
length still include only eligible unconfigured controllers.

Fixes: 73d1df2a7a10 ("Bluetooth: Add support for Read Unconfigured Index List command")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f740e745ae78..41956cdde982 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -496,13 +496,9 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
 
 	read_lock(&hci_dev_list_lock);
 
-	count = 0;
-	list_for_each_entry(d, &hci_dev_list, list) {
-		if (hci_dev_test_flag(d, HCI_UNCONFIGURED))
-			count++;
-	}
+	count = list_count_nodes(&hci_dev_list);
 
-	rp_len = sizeof(*rp) + (2 * count);
+	rp_len = sizeof(*rp) + (sizeof(__le16) * count);
 	rp = kmalloc(rp_len, GFP_ATOMIC);
 	if (!rp) {
 		read_unlock(&hci_dev_list_lock);


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 5.15.y 1/3] Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect()
  2026-09-29 11:49 FAILED: patch "[PATCH] Bluetooth: mgmt: fix race in read_unconf_index_list()" failed to apply to 5.15-stable tree gregkh
@ 2026-09-30 18:28 ` Sasha Levin
  2026-09-30 18:28   ` [PATCH 5.15.y 2/3] Bluetooth: HCI: Remove HCI_AMP support Sasha Levin
  2026-09-30 18:28   ` [PATCH 5.15.y 3/3] Bluetooth: mgmt: fix race in read_unconf_index_list() Sasha Levin
  0 siblings, 2 replies; 4+ messages in thread
From: Sasha Levin @ 2026-09-30 18:28 UTC (permalink / raw)
  To: stable; +Cc: Sungwoo Kim, Luiz Augusto von Dentz, Sasha Levin

From: Sungwoo Kim <iam@sung-woo.kim>

[ Upstream commit 4d7b41c0e43995b0e992b9f8903109275744b658 ]

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

Fixes: 73ffa904b782 ("Bluetooth: Move conf_{req,rsp} stuff to struct l2cap_chan")
Signed-off-by: Sungwoo Kim <iam@sung-woo.kim>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Stable-dep-of: b5dbb41b212c ("Bluetooth: mgmt: fix race in read_unconf_index_list()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/l2cap_core.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 34f89f7f993be..0140f82fdc8df 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4201,13 +4201,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);
@@ -4220,7 +4219,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);
@@ -4309,17 +4308,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);
@@ -4342,7 +4339,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,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 5.15.y 2/3] Bluetooth: HCI: Remove HCI_AMP support
  2026-09-30 18:28 ` [PATCH 5.15.y 1/3] Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect() Sasha Levin
@ 2026-09-30 18:28   ` Sasha Levin
  2026-09-30 18:28   ` [PATCH 5.15.y 3/3] Bluetooth: mgmt: fix race in read_unconf_index_list() Sasha Levin
  1 sibling, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-09-30 18:28 UTC (permalink / raw)
  To: stable; +Cc: Luiz Augusto von Dentz, Sasha Levin

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

[ Upstream commit 84a4bb6548a29326564f0e659fb8064503ecc1c7 ]

Since BT_HS has been remove HCI_AMP controllers no longer has any use so
remove it along with the capability of creating AMP controllers.

Since we no longer need to differentiate between AMP and Primary
controllers, as only HCI_PRIMARY is left, this also remove
hdev->dev_type altogether.

Fixes: e7b02296fb40 ("Bluetooth: Remove BT_HS")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Stable backport scope: retain only the read_unconf_index_list()
allocation-counting change needed by b5dbb41b212c ("Bluetooth: mgmt:
fix race in read_unconf_index_list()"). Drop the HCI_PRIMARY test from
that first pass so the target patch applies without conflicts.

Keep the HCI_PRIMARY test in the response-filling pass. Counting an
unconfigured AMP controller can only reserve extra space; the returned
controller list and response length still include only primary devices.
The target subsequently replaces this flag-dependent count with a count
of every device on the locked list to fix the race.

Linux 5.15 still has BT_HS/AMP support and lacks hci_bcm4377.c and
hci_sync.c. Drop all remaining upstream hunks rather than removing
fields, handlers and driver support that this tree still uses.

The preceding l2cap_connect() UAF fix made its return type void, but the
5.15 AMP create-channel caller still consumes that return value, causing
an allmodconfig build failure. Pass the referenced AMP device into
l2cap_connect() and move the existing AMP channel setup into its locked
region. This retains the void return type and protects the channel until
AMP setup finishes. The caller retains ownership of the device reference
and releases it after l2cap_connect() returns. No new functions are added.

[ sashal: Reduced backport -- upstream 84a4bb6548a29 touches 20 file(s), this
  backport carries 2. Not backported here:
  drivers/bluetooth/btmrvl_main.c
  drivers/bluetooth/btrsi.c
  drivers/bluetooth/btsdio.c
  drivers/bluetooth/btusb.c
  drivers/bluetooth/hci_bcm4377.c
  drivers/bluetooth/hci_ldisc.c
  drivers/bluetooth/hci_serdev.c
  drivers/bluetooth/hci_uart.h
  ... and 10 more
  This note is generated from the file lists only; see the resolution record
  for the reasoning. ]

Stable-dep-of: b5dbb41b212c ("Bluetooth: mgmt: fix race in read_unconf_index_list()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/l2cap_core.c | 58 +++++++++++++++++++-------------------
 net/bluetooth/mgmt.c       |  3 +-
 2 files changed, 30 insertions(+), 31 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 0140f82fdc8df..093b8dd184dad 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -58,6 +58,8 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
 			   void *data);
 static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size);
 static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
+static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
+				   u16 scid, u16 dcid);
 
 static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
 		     struct sk_buff_head *skbs, u8 event);
@@ -4202,7 +4204,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn,
 }
 
 static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
-			  u8 *data, u8 rsp_code, u8 amp_id)
+			  u8 *data, u8 rsp_code, struct hci_dev *amp_hdev)
 {
 	struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
 	struct l2cap_conn_rsp rsp;
@@ -4265,7 +4267,7 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
 	chan->dst_type = bdaddr_dst_type(conn->hcon);
 	chan->psm  = psm;
 	chan->dcid = scid;
-	chan->local_amp_id = amp_id;
+	chan->local_amp_id = amp_hdev ? amp_hdev->id : AMP_ID_BREDR;
 
 	__l2cap_chan_add(conn, chan);
 
@@ -4287,7 +4289,7 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
 				 * The connection will succeed after the
 				 * physical link is up.
 				 */
-				if (amp_id == AMP_ID_BREDR) {
+				if (!amp_hdev) {
 					l2cap_state_change(chan, BT_CONFIG);
 					result = L2CAP_CR_SUCCESS;
 				} else {
@@ -4339,6 +4341,27 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
 		chan->num_conf_req++;
 	}
 
+	/* Finish AMP setup while the new channel is protected. */
+	if (chan && amp_hdev) {
+		struct amp_mgr *mgr = conn->hcon->amp_mgr;
+		struct hci_conn *hs_hcon;
+
+		hs_hcon = hci_conn_hash_lookup_ba(amp_hdev, AMP_LINK,
+						  &conn->hcon->dst);
+		if (!hs_hcon) {
+			cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
+					       chan->dcid);
+		} else {
+			BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan,
+			       hs_hcon);
+
+			mgr->bredr_chan = chan;
+			chan->hs_hcon = hs_hcon;
+			chan->fcs = L2CAP_FCS_NONE;
+			conn->mtu = amp_hdev->block_mtu;
+		}
+	}
+
 	l2cap_chan_unlock(pchan);
 	mutex_unlock(&conn->chan_lock);
 	l2cap_chan_put(pchan);
@@ -4350,7 +4373,7 @@ static int l2cap_connect_req(struct l2cap_conn *conn,
 	if (cmd_len < sizeof(struct l2cap_conn_req))
 		return -EPROTO;
 
-	l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
+	l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, NULL);
 	return 0;
 }
 
@@ -4917,7 +4940,6 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn,
 {
 	struct l2cap_create_chan_req *req = data;
 	struct l2cap_create_chan_rsp rsp;
-	struct l2cap_chan *chan;
 	struct hci_dev *hdev;
 	u16 psm, scid;
 
@@ -4934,8 +4956,7 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn,
 
 	/* For controller id 0 make BR/EDR connection */
 	if (req->amp_id == AMP_ID_BREDR) {
-		l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
-			      req->amp_id);
+		l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, NULL);
 		return 0;
 	}
 
@@ -4949,28 +4970,7 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn,
 		goto error;
 	}
 
-	chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
-			     req->amp_id);
-	if (chan) {
-		struct amp_mgr *mgr = conn->hcon->amp_mgr;
-		struct hci_conn *hs_hcon;
-
-		hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
-						  &conn->hcon->dst);
-		if (!hs_hcon) {
-			hci_dev_put(hdev);
-			cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
-					       chan->dcid);
-			return 0;
-		}
-
-		BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
-
-		mgr->bredr_chan = chan;
-		chan->hs_hcon = hs_hcon;
-		chan->fcs = L2CAP_FCS_NONE;
-		conn->mtu = hdev->block_mtu;
-	}
+	l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, hdev);
 
 	hci_dev_put(hdev);
 
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 5b67247587ba6..8a1fc2d252800 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -460,8 +460,7 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
 
 	count = 0;
 	list_for_each_entry(d, &hci_dev_list, list) {
-		if (d->dev_type == HCI_PRIMARY &&
-		    hci_dev_test_flag(d, HCI_UNCONFIGURED))
+		if (hci_dev_test_flag(d, HCI_UNCONFIGURED))
 			count++;
 	}
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 5.15.y 3/3] Bluetooth: mgmt: fix race in read_unconf_index_list()
  2026-09-30 18:28 ` [PATCH 5.15.y 1/3] Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect() Sasha Levin
  2026-09-30 18:28   ` [PATCH 5.15.y 2/3] Bluetooth: HCI: Remove HCI_AMP support Sasha Levin
@ 2026-09-30 18:28   ` Sasha Levin
  1 sibling, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-09-30 18:28 UTC (permalink / raw)
  To: stable; +Cc: Aldo Ariel Panzardo, Luiz Augusto von Dentz, Sasha Levin

From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>

[ Upstream commit b5dbb41b212c50c095a4dbee3017a84fe94f033b ]

read_unconf_index_list() counts unconfigured controllers before allocating
its response, then checks the device flags again while filling it.

hci_dev_list_lock stabilizes list membership, but it does not serialize the
per-device flags. During asynchronous controller setup, the worker can set
HCI_UNCONFIGURED and clear HCI_SETUP between the two passes. A controller
omitted from the allocation count can then become eligible for the fill
pass, causing an out-of-bounds write to rp->index[].

Allocate space for every device on hci_dev_list. Since list membership
cannot change while hci_dev_list_lock is held, the response remains large
enough regardless of flag transitions. The reported count and response
length still include only eligible unconfigured controllers.

Fixes: 73d1df2a7a10 ("Bluetooth: Add support for Read Unconfigured Index List command")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ Replaced unavailable list_count_nodes() with a list_for_each_entry() loop that increments count unconditionally. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/mgmt.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 8a1fc2d252800..76d7dd7772255 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -459,12 +459,10 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
 	read_lock(&hci_dev_list_lock);
 
 	count = 0;
-	list_for_each_entry(d, &hci_dev_list, list) {
-		if (hci_dev_test_flag(d, HCI_UNCONFIGURED))
-			count++;
-	}
+	list_for_each_entry(d, &hci_dev_list, list)
+		count++;
 
-	rp_len = sizeof(*rp) + (2 * count);
+	rp_len = sizeof(*rp) + (sizeof(__le16) * count);
 	rp = kmalloc(rp_len, GFP_ATOMIC);
 	if (!rp) {
 		read_unlock(&hci_dev_list_lock);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-09-30 18:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-29 11:49 FAILED: patch "[PATCH] Bluetooth: mgmt: fix race in read_unconf_index_list()" failed to apply to 5.15-stable tree gregkh
2026-09-30 18:28 ` [PATCH 5.15.y 1/3] Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect() Sasha Levin
2026-09-30 18:28   ` [PATCH 5.15.y 2/3] Bluetooth: HCI: Remove HCI_AMP support Sasha Levin
2026-09-30 18:28   ` [PATCH 5.15.y 3/3] Bluetooth: mgmt: fix race in read_unconf_index_list() Sasha Levin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.