FAILED: patch "[PATCH] Bluetooth: L2CAP: cancel pending_rx_work before taking" 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 2641a9e0a1dd4af2e21995470a21d55dd35e5203
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026071336-evolve-imaging-b852@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2641a9e0a1dd4af2e21995470a21d55dd35e5203 Mon Sep 17 00:00:00 2001
From: Runyu Xiao <[email protected]>
Date: Wed, 17 Jun 2026 23:36:13 +0800
Subject: [PATCH] Bluetooth: L2CAP: cancel pending_rx_work before taking
conn->lock
l2cap_conn_del() takes conn->lock and then calls cancel_work_sync() for pending_rx_work. process_pending_rx() takes the same mutex, so teardown can deadlock against the worker it is flushing.
This issue was found by our static analysis tool and then manually reviewed against the current tree.
The grounded PoC kept the l2cap_conn_ready() -> queue_work(..., &conn->pending_rx_work) submit path, the l2cap_conn_del() -> cancel_work_sync(&conn->pending_rx_work) teardown path, and the process_pending_rx() -> mutex_lock(&conn->lock) worker edge. Lockdep reported:
WARNING: possible circular locking dependency detected
process_pending_rx+0x21/0x2a [vuln_msv] l2cap_conn_del.constprop.0+0x3f/0x4e [vuln_msv] *** DEADLOCK ***
Cancel pending_rx_work before taking conn->lock, matching the existing lock-before-drain ordering used for the two delayed works in the same teardown path. The pending_rx queue is still purged after the work has been cancelled and conn->lock has been acquired.
net/bluetooth/l2cap_core.c +2 -8
@@ -1775,19 +1775,13 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)disable_delayed_work_sync (&conn->info_timer);disable_delayed_work_sync (&conn->id_addr_timer); +cancel_work_sync (&conn->pending_rx_work); +mutex_lock (&conn->lock);kfree_skb (conn->rx_skb);skb_queue_purge (&conn->pending_rx); - -/* We can not call flush_work(&conn->pending_rx_work) here since we -* might block if we are running on a worker from the same workqueue -* pending_rx_work is waiting on. -*/ -if (work_pending (&conn->pending_rx_work)) -cancel_work_sync (&conn->pending_rx_work); -ida_destroy (&conn->tx_ida);l2cap_unregister_all_users (conn);
Sasha Levin
maintainerPATCH 1/3 Bluetooth: L2CAP: Fix not tracking outstanding TX ident
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 6c3ea155e5ee3e56606233acde8309afda66d483 ]
This attempts to proper track outstanding request by using struct ida and allocating from it in l2cap_get_ident using ida_alloc_range which would reuse ids as they are free, then upon completion release the id using ida_free.
This fixes the qualification test case L2CAP/COS/CED/BI-29-C which attempts to check if the host stack is able to work after 256 attempts to connect which requires Ident field to use the full range of possible values in order to pass the test.
Stable-dep-of: 2641a9e0a1dd ("Bluetooth: L2CAP: cancel pending_rx_work before taking conn->lock")
--- include/net/bluetooth/l2cap.h | 3 +- net/bluetooth/l2cap_core.c | 53 ++++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 16 deletions(-)
include/net/bluetooth/l2cap.h +1 -2
@@ -691,8 +691,7 @@ struct l2cap_conn {struct sk_buff *rx_skb;__u32 rx_len; -__u8 tx_ident; -struct mutex ident_lock; +struct ida tx_ida;struct sk_buff_head pending_rx;struct work_struct pending_rx_work;
net/bluetooth/l2cap_core.c +39 -14
102 lines not on this page · raw message
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/3 Bluetooth: L2CAP: Fix deadlock in l2cap_conn_del()
From: Hyunwoo Kim <[email protected]>
[ Upstream commit 00fdebbbc557a2fc21321ff2eaa22fd70c078608 ]
l2cap_conn_del() calls cancel_delayed_work_sync() for both info_timer and id_addr_timer while holding conn->lock. However, the work functions l2cap_info_timeout() and l2cap_conn_update_id_addr() both acquire conn->lock, creating a potential AB-BA deadlock if the work is already executing when l2cap_conn_del() takes the lock.
Move the work cancellations before acquiring conn->lock and use disable_delayed_work_sync() to additionally prevent the works from being rearmed after cancellation, consistent with the pattern used in hci_conn_del().
Stable-dep-of: 2641a9e0a1dd ("Bluetooth: L2CAP: cancel pending_rx_work before taking conn->lock")
--- net/bluetooth/l2cap_core.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
net/bluetooth/l2cap_core.c +3 -6
@@ -1896,6 +1896,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)BT_DBG ("hcon %p conn %p, err %d" , hcon, conn, err); +cancel_delayed_work_sync (&conn->info_timer); +cancel_work_sync (&conn->id_addr_update_work); +kfree_skb (conn->rx_skb);skb_queue_purge (&conn->pending_rx);
@@ -1909,9 +1912,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)ida_destroy (&conn->tx_ida); -if (work_pending (&conn->id_addr_update_work)) -cancel_work_sync (&conn->id_addr_update_work); -l2cap_unregister_all_users (conn);/* Force the connection to be immediately dropped */
@@ -1936,9 +1936,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)hci_chan_del (conn->hchan); -if (conn->info_state &L2CAP_INFO_FEAT_MASK_REQ_SENT ) -cancel_delayed_work_sync (&conn->info_timer); - hcon->l2cap_data =NULL ; conn->hchan =NULL ;l2cap_conn_put (conn);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/3 Bluetooth: L2CAP: cancel pending_rx_work before taking conn->lock
In reply to Sasha LevinFrom: Runyu Xiao <[email protected]>
[ Upstream commit 2641a9e0a1dd4af2e21995470a21d55dd35e5203 ]
l2cap_conn_del() takes conn->lock and then calls cancel_work_sync() for pending_rx_work. process_pending_rx() takes the same mutex, so teardown can deadlock against the worker it is flushing.
This issue was found by our static analysis tool and then manually reviewed against the current tree.
The grounded PoC kept the l2cap_conn_ready() -> queue_work(..., &conn->pending_rx_work) submit path, the l2cap_conn_del() -> cancel_work_sync(&conn->pending_rx_work) teardown path, and the process_pending_rx() -> mutex_lock(&conn->lock) worker edge. Lockdep reported:
WARNING: possible circular locking dependency detected
process_pending_rx+0x21/0x2a [vuln_msv] l2cap_conn_del.constprop.0+0x3f/0x4e [vuln_msv] *** DEADLOCK ***
Cancel pending_rx_work before taking conn->lock, matching the existing lock-before-drain ordering used for the two delayed works in the same teardown path. The pending_rx queue is still purged after the work has been cancelled and conn->lock has been acquired.
--- net/bluetooth/l2cap_core.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
net/bluetooth/l2cap_core.c +2 -8
@@ -1899,17 +1899,11 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)cancel_delayed_work_sync (&conn->info_timer);cancel_work_sync (&conn->id_addr_update_work); +cancel_work_sync (&conn->pending_rx_work); +kfree_skb (conn->rx_skb);skb_queue_purge (&conn->pending_rx); - -/* We can not call flush_work(&conn->pending_rx_work) here since we -* might block if we are running on a worker from the same workqueue -* pending_rx_work is waiting on. -*/ -if (work_pending (&conn->pending_rx_work)) -cancel_work_sync (&conn->pending_rx_work); -ida_destroy (&conn->tx_ida);l2cap_unregister_all_users (conn);
Signature · 1 line
2.53.0