mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git
synced 2026-04-01 22:38:17 -04:00
Bluetooth: L2CAP: Fix deadlock in l2cap_conn_del()
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().
Fixes: ab4eedb790 ("Bluetooth: L2CAP: Fix corrupted list in hci_chan_del")
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
committed by
Luiz Augusto von Dentz
parent
94d8e6fe5d
commit
00fdebbbc5
@@ -1771,6 +1771,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
|
||||
|
||||
BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
|
||||
|
||||
disable_delayed_work_sync(&conn->info_timer);
|
||||
disable_delayed_work_sync(&conn->id_addr_timer);
|
||||
|
||||
mutex_lock(&conn->lock);
|
||||
|
||||
kfree_skb(conn->rx_skb);
|
||||
@@ -1786,8 +1789,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
|
||||
|
||||
ida_destroy(&conn->tx_ida);
|
||||
|
||||
cancel_delayed_work_sync(&conn->id_addr_timer);
|
||||
|
||||
l2cap_unregister_all_users(conn);
|
||||
|
||||
/* Force the connection to be immediately dropped */
|
||||
@@ -1806,9 +1807,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
|
||||
l2cap_chan_put(chan);
|
||||
}
|
||||
|
||||
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
|
||||
cancel_delayed_work_sync(&conn->info_timer);
|
||||
|
||||
hci_chan_del(conn->hchan);
|
||||
conn->hchan = NULL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user