From: Greg Kroah-Hartman Date: Thu, 14 Nov 2024 12:30:24 +0000 (+0100) Subject: 6.1-stable patches X-Git-Tag: v4.19.324~35 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f86fe291cd82b74b75c0e3ff5cdc4e8085342341;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: revert-bluetooth-af_bluetooth-fix-deadlock.patch revert-bluetooth-fix-use-after-free-in-accessing-skb-after-sending-it.patch revert-bluetooth-hci_conn-consolidate-code-for-aborting-connections.patch revert-bluetooth-hci_core-fix-possible-buffer-overflow.patch revert-bluetooth-hci_sync-fix-overwriting-request-callback.patch series --- diff --git a/queue-6.1/revert-bluetooth-af_bluetooth-fix-deadlock.patch b/queue-6.1/revert-bluetooth-af_bluetooth-fix-deadlock.patch new file mode 100644 index 00000000000..731dfea1855 --- /dev/null +++ b/queue-6.1/revert-bluetooth-af_bluetooth-fix-deadlock.patch @@ -0,0 +1,68 @@ +From 1b8851da51113f6a7f01297823eaf22b4b772063 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 13 Nov 2024 15:43:55 +0100 +Subject: Revert "Bluetooth: af_bluetooth: Fix deadlock" + +From: Greg Kroah-Hartman + +This reverts commit cb8adca52f306563d958a863bb0cbae9c184d1ae which is +commit f7b94bdc1ec107c92262716b073b3e816d4784fb upstream. + +It is reported to cause regressions in the 6.1.y tree, so revert it for +now. + +Link: https://lore.kernel.org/all/CADRbXaDqx6S+7tzdDPPEpRu9eDLrHQkqoWTTGfKJSRxY=hT5MQ@mail.gmail.com/ +Reported-by: Jeremy Lainé +Cc: Salvatore Bonaccorso +Cc: Mike +Cc: Marcel Holtmann +Cc: Johan Hedberg +Cc: Paul Menzel +Cc: Pauli Virtanen +Cc: Luiz Augusto von Dentz +Cc: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/af_bluetooth.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/net/bluetooth/af_bluetooth.c ++++ b/net/bluetooth/af_bluetooth.c +@@ -307,11 +307,14 @@ int bt_sock_recvmsg(struct socket *sock, + if (flags & MSG_OOB) + return -EOPNOTSUPP; + ++ lock_sock(sk); ++ + skb = skb_recv_datagram(sk, flags, &err); + if (!skb) { + if (sk->sk_shutdown & RCV_SHUTDOWN) + err = 0; + ++ release_sock(sk); + return err; + } + +@@ -337,6 +340,8 @@ int bt_sock_recvmsg(struct socket *sock, + + skb_free_datagram(sk, skb); + ++ release_sock(sk); ++ + if (flags & MSG_TRUNC) + copied = skblen; + +@@ -559,11 +564,10 @@ int bt_sock_ioctl(struct socket *sock, u + if (sk->sk_state == BT_LISTEN) + return -EINVAL; + +- spin_lock(&sk->sk_receive_queue.lock); ++ lock_sock(sk); + skb = skb_peek(&sk->sk_receive_queue); + amount = skb ? skb->len : 0; +- spin_unlock(&sk->sk_receive_queue.lock); +- ++ release_sock(sk); + err = put_user(amount, (int __user *)arg); + break; + diff --git a/queue-6.1/revert-bluetooth-fix-use-after-free-in-accessing-skb-after-sending-it.patch b/queue-6.1/revert-bluetooth-fix-use-after-free-in-accessing-skb-after-sending-it.patch new file mode 100644 index 00000000000..f42686efdc6 --- /dev/null +++ b/queue-6.1/revert-bluetooth-fix-use-after-free-in-accessing-skb-after-sending-it.patch @@ -0,0 +1,39 @@ +From bb6015962fa5e0f3b624c605e502fc0b29c325ff Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 13 Nov 2024 15:42:18 +0100 +Subject: Revert "Bluetooth: fix use-after-free in accessing skb after sending it" + +From: Greg Kroah-Hartman + +This reverts commit 715264ad09fd4004e347cdb79fa58a4f2344f13f which is +commit 947ec0d002dce8577b655793dcc6fc78d67b7cb6 upstream. + +It is reported to cause regressions in the 6.1.y tree, so revert it for +now. + +Link: https://lore.kernel.org/all/CADRbXaDqx6S+7tzdDPPEpRu9eDLrHQkqoWTTGfKJSRxY=hT5MQ@mail.gmail.com/ +Reported-by: Jeremy Lainé +Cc: Salvatore Bonaccorso +Cc: Mike +Cc: Marcel Holtmann +Cc: Johan Hedberg +Cc: Paul Menzel +Cc: Pauli Virtanen +Cc: Luiz Augusto von Dentz +Cc: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/hci_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -4146,7 +4146,7 @@ static void hci_send_cmd_sync(struct hci + if (hci_req_status_pend(hdev) && + !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) { + kfree_skb(hdev->req_skb); +- hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); ++ hdev->req_skb = skb_clone(skb, GFP_KERNEL); + } + + atomic_dec(&hdev->cmd_cnt); diff --git a/queue-6.1/revert-bluetooth-hci_conn-consolidate-code-for-aborting-connections.patch b/queue-6.1/revert-bluetooth-hci_conn-consolidate-code-for-aborting-connections.patch new file mode 100644 index 00000000000..40df2225fe3 --- /dev/null +++ b/queue-6.1/revert-bluetooth-hci_conn-consolidate-code-for-aborting-connections.patch @@ -0,0 +1,333 @@ +From 898205b3df400a1d9e8311778fae9219e526c444 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 13 Nov 2024 15:45:02 +0100 +Subject: Revert "Bluetooth: hci_conn: Consolidate code for aborting connections" + +From: Greg Kroah-Hartman + +This reverts commit 6083089ab00631617f9eac678df3ab050a9d837a which is +commit a13f316e90fdb1fb6df6582e845aa9b3270f3581 upstream. + +It is reported to cause regressions in the 6.1.y tree, so revert it for +now. + +Link: https://lore.kernel.org/all/CADRbXaDqx6S+7tzdDPPEpRu9eDLrHQkqoWTTGfKJSRxY=hT5MQ@mail.gmail.com/ +Reported-by: Jeremy Lainé +Cc: Salvatore Bonaccorso +Cc: Mike +Cc: Marcel Holtmann +Cc: Johan Hedberg +Cc: Paul Menzel +Cc: Pauli Virtanen +Cc: Luiz Augusto von Dentz +Cc: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/net/bluetooth/hci_core.h | 2 + net/bluetooth/hci_conn.c | 156 +++++++++++++++++++++++++++++++-------- + net/bluetooth/hci_sync.c | 23 ++--- + net/bluetooth/mgmt.c | 15 +++ + 4 files changed, 148 insertions(+), 48 deletions(-) + +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -734,7 +734,6 @@ struct hci_conn { + unsigned long flags; + + enum conn_reasons conn_reason; +- __u8 abort_reason; + + __u32 clock; + __u16 clock_accuracy; +@@ -754,6 +753,7 @@ struct hci_conn { + struct delayed_work auto_accept_work; + struct delayed_work idle_work; + struct delayed_work le_conn_timeout; ++ struct work_struct le_scan_cleanup; + + struct device dev; + struct dentry *debugfs; +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -174,6 +174,57 @@ static void hci_conn_cleanup(struct hci_ + hci_dev_put(hdev); + } + ++static void le_scan_cleanup(struct work_struct *work) ++{ ++ struct hci_conn *conn = container_of(work, struct hci_conn, ++ le_scan_cleanup); ++ struct hci_dev *hdev = conn->hdev; ++ struct hci_conn *c = NULL; ++ ++ BT_DBG("%s hcon %p", hdev->name, conn); ++ ++ hci_dev_lock(hdev); ++ ++ /* Check that the hci_conn is still around */ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(c, &hdev->conn_hash.list, list) { ++ if (c == conn) ++ break; ++ } ++ rcu_read_unlock(); ++ ++ if (c == conn) { ++ hci_connect_le_scan_cleanup(conn, 0x00); ++ hci_conn_cleanup(conn); ++ } ++ ++ hci_dev_unlock(hdev); ++ hci_dev_put(hdev); ++ hci_conn_put(conn); ++} ++ ++static void hci_connect_le_scan_remove(struct hci_conn *conn) ++{ ++ BT_DBG("%s hcon %p", conn->hdev->name, conn); ++ ++ /* We can't call hci_conn_del/hci_conn_cleanup here since that ++ * could deadlock with another hci_conn_del() call that's holding ++ * hci_dev_lock and doing cancel_delayed_work_sync(&conn->disc_work). ++ * Instead, grab temporary extra references to the hci_dev and ++ * hci_conn and perform the necessary cleanup in a separate work ++ * callback. ++ */ ++ ++ hci_dev_hold(conn->hdev); ++ hci_conn_get(conn); ++ ++ /* Even though we hold a reference to the hdev, many other ++ * things might get cleaned up meanwhile, including the hdev's ++ * own workqueue, so we can't use that for scheduling. ++ */ ++ schedule_work(&conn->le_scan_cleanup); ++} ++ + static void hci_acl_create_connection(struct hci_conn *conn) + { + struct hci_dev *hdev = conn->hdev; +@@ -625,6 +676,13 @@ static void hci_conn_timeout(struct work + if (refcnt > 0) + return; + ++ /* LE connections in scanning state need special handling */ ++ if (conn->state == BT_CONNECT && conn->type == LE_LINK && ++ test_bit(HCI_CONN_SCANNING, &conn->flags)) { ++ hci_connect_le_scan_remove(conn); ++ return; ++ } ++ + hci_abort_conn(conn, hci_proto_disconn_ind(conn)); + } + +@@ -996,6 +1054,7 @@ struct hci_conn *hci_conn_add(struct hci + INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept); + INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle); + INIT_DELAYED_WORK(&conn->le_conn_timeout, le_conn_timeout); ++ INIT_WORK(&conn->le_scan_cleanup, le_scan_cleanup); + + atomic_set(&conn->refcnt, 0); + +@@ -2781,46 +2840,81 @@ u32 hci_conn_get_phy(struct hci_conn *co + return phys; + } + +-static int abort_conn_sync(struct hci_dev *hdev, void *data) ++int hci_abort_conn(struct hci_conn *conn, u8 reason) + { +- struct hci_conn *conn; +- u16 handle = PTR_ERR(data); ++ int r = 0; + +- conn = hci_conn_hash_lookup_handle(hdev, handle); +- if (!conn) ++ if (test_and_set_bit(HCI_CONN_CANCEL, &conn->flags)) + return 0; + +- return hci_abort_conn_sync(hdev, conn, conn->abort_reason); +-} +- +-int hci_abort_conn(struct hci_conn *conn, u8 reason) +-{ +- struct hci_dev *hdev = conn->hdev; ++ switch (conn->state) { ++ case BT_CONNECTED: ++ case BT_CONFIG: ++ if (conn->type == AMP_LINK) { ++ struct hci_cp_disconn_phy_link cp; ++ ++ cp.phy_handle = HCI_PHY_HANDLE(conn->handle); ++ cp.reason = reason; ++ r = hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK, ++ sizeof(cp), &cp); ++ } else { ++ struct hci_cp_disconnect dc; + +- /* If abort_reason has already been set it means the connection is +- * already being aborted so don't attempt to overwrite it. +- */ +- if (conn->abort_reason) +- return 0; ++ dc.handle = cpu_to_le16(conn->handle); ++ dc.reason = reason; ++ r = hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, ++ sizeof(dc), &dc); ++ } + +- bt_dev_dbg(hdev, "handle 0x%2.2x reason 0x%2.2x", conn->handle, reason); ++ conn->state = BT_DISCONN; + +- conn->abort_reason = reason; ++ break; ++ case BT_CONNECT: ++ if (conn->type == LE_LINK) { ++ if (test_bit(HCI_CONN_SCANNING, &conn->flags)) ++ break; ++ r = hci_send_cmd(conn->hdev, ++ HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL); ++ } else if (conn->type == ACL_LINK) { ++ if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2) ++ break; ++ r = hci_send_cmd(conn->hdev, ++ HCI_OP_CREATE_CONN_CANCEL, ++ 6, &conn->dst); ++ } ++ break; ++ case BT_CONNECT2: ++ if (conn->type == ACL_LINK) { ++ struct hci_cp_reject_conn_req rej; ++ ++ bacpy(&rej.bdaddr, &conn->dst); ++ rej.reason = reason; ++ ++ r = hci_send_cmd(conn->hdev, ++ HCI_OP_REJECT_CONN_REQ, ++ sizeof(rej), &rej); ++ } else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) { ++ struct hci_cp_reject_sync_conn_req rej; ++ ++ bacpy(&rej.bdaddr, &conn->dst); ++ ++ /* SCO rejection has its own limited set of ++ * allowed error values (0x0D-0x0F) which isn't ++ * compatible with most values passed to this ++ * function. To be safe hard-code one of the ++ * values that's suitable for SCO. ++ */ ++ rej.reason = HCI_ERROR_REJ_LIMITED_RESOURCES; + +- /* If the connection is pending check the command opcode since that +- * might be blocking on hci_cmd_sync_work while waiting its respective +- * event so we need to hci_cmd_sync_cancel to cancel it. +- */ +- if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) { +- switch (hci_skb_event(hdev->sent_cmd)) { +- case HCI_EV_LE_CONN_COMPLETE: +- case HCI_EV_LE_ENHANCED_CONN_COMPLETE: +- case HCI_EVT_LE_CIS_ESTABLISHED: +- hci_cmd_sync_cancel(hdev, -ECANCELED); +- break; ++ r = hci_send_cmd(conn->hdev, ++ HCI_OP_REJECT_SYNC_CONN_REQ, ++ sizeof(rej), &rej); + } ++ break; ++ default: ++ conn->state = BT_CLOSED; ++ break; + } + +- return hci_cmd_sync_queue(hdev, abort_conn_sync, ERR_PTR(conn->handle), +- NULL); ++ return r; + } +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -5293,27 +5293,22 @@ static int hci_disconnect_sync(struct hc + } + + static int hci_le_connect_cancel_sync(struct hci_dev *hdev, +- struct hci_conn *conn, u8 reason) ++ struct hci_conn *conn) + { +- /* Return reason if scanning since the connection shall probably be +- * cleanup directly. +- */ + if (test_bit(HCI_CONN_SCANNING, &conn->flags)) +- return reason; ++ return 0; + +- if (conn->role == HCI_ROLE_SLAVE || +- test_and_set_bit(HCI_CONN_CANCEL, &conn->flags)) ++ if (test_and_set_bit(HCI_CONN_CANCEL, &conn->flags)) + return 0; + + return __hci_cmd_sync_status(hdev, HCI_OP_LE_CREATE_CONN_CANCEL, + 0, NULL, HCI_CMD_TIMEOUT); + } + +-static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn, +- u8 reason) ++static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn) + { + if (conn->type == LE_LINK) +- return hci_le_connect_cancel_sync(hdev, conn, reason); ++ return hci_le_connect_cancel_sync(hdev, conn); + + if (hdev->hci_ver < BLUETOOTH_VER_1_2) + return 0; +@@ -5366,11 +5361,9 @@ int hci_abort_conn_sync(struct hci_dev * + case BT_CONFIG: + return hci_disconnect_sync(hdev, conn, reason); + case BT_CONNECT: +- err = hci_connect_cancel_sync(hdev, conn, reason); ++ err = hci_connect_cancel_sync(hdev, conn); + /* Cleanup hci_conn object if it cannot be cancelled as it +- * likelly means the controller and host stack are out of sync +- * or in case of LE it was still scanning so it can be cleanup +- * safely. ++ * likelly means the controller and host stack are out of sync. + */ + if (err) { + hci_dev_lock(hdev); +@@ -6285,7 +6278,7 @@ int hci_le_create_conn_sync(struct hci_d + + done: + if (err == -ETIMEDOUT) +- hci_le_connect_cancel_sync(hdev, conn, 0x00); ++ hci_le_connect_cancel_sync(hdev, conn); + + /* Re-enable advertising after the connection attempt is finished. */ + hci_resume_advertising_sync(hdev); +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -3600,6 +3600,18 @@ unlock: + return err; + } + ++static int abort_conn_sync(struct hci_dev *hdev, void *data) ++{ ++ struct hci_conn *conn; ++ u16 handle = PTR_ERR(data); ++ ++ conn = hci_conn_hash_lookup_handle(hdev, handle); ++ if (!conn) ++ return 0; ++ ++ return hci_abort_conn_sync(hdev, conn, HCI_ERROR_REMOTE_USER_TERM); ++} ++ + static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data, + u16 len) + { +@@ -3650,7 +3662,8 @@ static int cancel_pair_device(struct soc + le_addr_type(addr->type)); + + if (conn->conn_reason == CONN_REASON_PAIR_DEVICE) +- hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM); ++ hci_cmd_sync_queue(hdev, abort_conn_sync, ERR_PTR(conn->handle), ++ NULL); + + unlock: + hci_dev_unlock(hdev); diff --git a/queue-6.1/revert-bluetooth-hci_core-fix-possible-buffer-overflow.patch b/queue-6.1/revert-bluetooth-hci_core-fix-possible-buffer-overflow.patch new file mode 100644 index 00000000000..85d3f9fe74f --- /dev/null +++ b/queue-6.1/revert-bluetooth-hci_core-fix-possible-buffer-overflow.patch @@ -0,0 +1,39 @@ +From ed41cfef23ae134993de32a77ed6a30df2b5bb2a Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 13 Nov 2024 15:44:07 +0100 +Subject: Revert "Bluetooth: hci_core: Fix possible buffer overflow" + +From: Greg Kroah-Hartman + +This reverts commit 68644bf5ec6baaff40fc39b3529c874bfda709bd which is +commit 81137162bfaa7278785b24c1fd2e9e74f082e8e4 upstream. + +It is reported to cause regressions in the 6.1.y tree, so revert it for +now. + +Link: https://lore.kernel.org/all/CADRbXaDqx6S+7tzdDPPEpRu9eDLrHQkqoWTTGfKJSRxY=hT5MQ@mail.gmail.com/ +Reported-by: Jeremy Lainé +Cc: Salvatore Bonaccorso +Cc: Mike +Cc: Marcel Holtmann +Cc: Johan Hedberg +Cc: Paul Menzel +Cc: Pauli Virtanen +Cc: Luiz Augusto von Dentz +Cc: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/hci_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -869,7 +869,7 @@ int hci_get_dev_info(void __user *arg) + else + flags = hdev->flags; + +- strscpy(di.name, hdev->name, sizeof(di.name)); ++ strcpy(di.name, hdev->name); + di.bdaddr = hdev->bdaddr; + di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); + di.flags = flags; diff --git a/queue-6.1/revert-bluetooth-hci_sync-fix-overwriting-request-callback.patch b/queue-6.1/revert-bluetooth-hci_sync-fix-overwriting-request-callback.patch new file mode 100644 index 00000000000..0a5eca1032c --- /dev/null +++ b/queue-6.1/revert-bluetooth-hci_sync-fix-overwriting-request-callback.patch @@ -0,0 +1,251 @@ +From 9cb0d1e2bf8f7faeb42466768b46f0cf2da80941 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 13 Nov 2024 15:42:48 +0100 +Subject: Revert "Bluetooth: hci_sync: Fix overwriting request callback" + +From: Greg Kroah-Hartman + +This reverts commit da77c1d39bc527b31890bfa0405763c82828defb which is +commit 2615fd9a7c2507eb3be3fbe49dcec88a2f56454a upstream. + +It is reported to cause regressions in the 6.1.y tree, so revert it for +now. + +Link: https://lore.kernel.org/all/CADRbXaDqx6S+7tzdDPPEpRu9eDLrHQkqoWTTGfKJSRxY=hT5MQ@mail.gmail.com/ +Reported-by: Jeremy Lainé +Cc: Salvatore Bonaccorso +Cc: Mike +Cc: Marcel Holtmann +Cc: Johan Hedberg +Cc: Paul Menzel +Cc: Pauli Virtanen +Cc: Luiz Augusto von Dentz +Cc: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_conn.c | 2 - + net/bluetooth/hci_core.c | 46 +++++++++++---------------------------- + net/bluetooth/hci_event.c | 18 +++++++-------- + net/bluetooth/hci_sync.c | 21 ++--------------- + 5 files changed, 27 insertions(+), 61 deletions(-) + +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -544,7 +544,6 @@ struct hci_dev { + __u32 req_status; + __u32 req_result; + struct sk_buff *req_skb; +- struct sk_buff *req_rsp; + + void *smp_data; + void *smp_bredr_data; +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -2816,7 +2816,7 @@ int hci_abort_conn(struct hci_conn *conn + case HCI_EV_LE_CONN_COMPLETE: + case HCI_EV_LE_ENHANCED_CONN_COMPLETE: + case HCI_EVT_LE_CIS_ESTABLISHED: +- hci_cmd_sync_cancel(hdev, ECANCELED); ++ hci_cmd_sync_cancel(hdev, -ECANCELED); + break; + } + } +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -1452,8 +1452,8 @@ static void hci_cmd_timeout(struct work_ + struct hci_dev *hdev = container_of(work, struct hci_dev, + cmd_timer.work); + +- if (hdev->req_skb) { +- u16 opcode = hci_skb_opcode(hdev->req_skb); ++ if (hdev->sent_cmd) { ++ u16 opcode = hci_skb_opcode(hdev->sent_cmd); + + bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); + +@@ -2762,7 +2762,6 @@ void hci_release_dev(struct hci_dev *hde + + ida_simple_remove(&hci_index_ida, hdev->id); + kfree_skb(hdev->sent_cmd); +- kfree_skb(hdev->req_skb); + kfree_skb(hdev->recv_event); + kfree(hdev); + } +@@ -3092,33 +3091,21 @@ int __hci_cmd_send(struct hci_dev *hdev, + EXPORT_SYMBOL(__hci_cmd_send); + + /* Get data from the previously sent command */ +-static void *hci_cmd_data(struct sk_buff *skb, __u16 opcode) ++void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) + { + struct hci_command_hdr *hdr; + +- if (!skb || skb->len < HCI_COMMAND_HDR_SIZE) ++ if (!hdev->sent_cmd) + return NULL; + +- hdr = (void *)skb->data; ++ hdr = (void *) hdev->sent_cmd->data; + + if (hdr->opcode != cpu_to_le16(opcode)) + return NULL; + +- return skb->data + HCI_COMMAND_HDR_SIZE; +-} ++ BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); + +-/* Get data from the previously sent command */ +-void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) +-{ +- void *data; +- +- /* Check if opcode matches last sent command */ +- data = hci_cmd_data(hdev->sent_cmd, opcode); +- if (!data) +- /* Check if opcode matches last request */ +- data = hci_cmd_data(hdev->req_skb, opcode); +- +- return data; ++ return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; + } + + /* Get data from last received event */ +@@ -4014,19 +4001,17 @@ void hci_req_cmd_complete(struct hci_dev + if (!status && !hci_req_is_complete(hdev)) + return; + +- skb = hdev->req_skb; +- + /* If this was the last command in a request the complete +- * callback would be found in hdev->req_skb instead of the ++ * callback would be found in hdev->sent_cmd instead of the + * command queue (hdev->cmd_q). + */ +- if (skb && bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) { +- *req_complete_skb = bt_cb(skb)->hci.req_complete_skb; ++ if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) { ++ *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb; + return; + } + +- if (skb && bt_cb(skb)->hci.req_complete) { +- *req_complete = bt_cb(skb)->hci.req_complete; ++ if (bt_cb(hdev->sent_cmd)->hci.req_complete) { ++ *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete; + return; + } + +@@ -4143,11 +4128,8 @@ static void hci_send_cmd_sync(struct hci + return; + } + +- if (hci_req_status_pend(hdev) && +- !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) { +- kfree_skb(hdev->req_skb); +- hdev->req_skb = skb_clone(skb, GFP_KERNEL); +- } ++ if (hci_req_status_pend(hdev)) ++ hci_dev_set_flag(hdev, HCI_CMD_PENDING); + + atomic_dec(&hdev->cmd_cnt); + } +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -4354,7 +4354,7 @@ static void hci_cmd_status_evt(struct hc + * (since for this kind of commands there will not be a command + * complete event). + */ +- if (ev->status || (hdev->req_skb && !hci_skb_event(hdev->req_skb))) { ++ if (ev->status || (hdev->sent_cmd && !hci_skb_event(hdev->sent_cmd))) { + hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete, + req_complete_skb); + if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) { +@@ -7171,10 +7171,10 @@ static void hci_le_meta_evt(struct hci_d + bt_dev_dbg(hdev, "subevent 0x%2.2x", ev->subevent); + + /* Only match event if command OGF is for LE */ +- if (hdev->req_skb && +- hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) == 0x08 && +- hci_skb_event(hdev->req_skb) == ev->subevent) { +- *opcode = hci_skb_opcode(hdev->req_skb); ++ if (hdev->sent_cmd && ++ hci_opcode_ogf(hci_skb_opcode(hdev->sent_cmd)) == 0x08 && ++ hci_skb_event(hdev->sent_cmd) == ev->subevent) { ++ *opcode = hci_skb_opcode(hdev->sent_cmd); + hci_req_cmd_complete(hdev, *opcode, 0x00, req_complete, + req_complete_skb); + } +@@ -7561,10 +7561,10 @@ void hci_event_packet(struct hci_dev *hd + } + + /* Only match event if command OGF is not for LE */ +- if (hdev->req_skb && +- hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 && +- hci_skb_event(hdev->req_skb) == event) { +- hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->req_skb), ++ if (hdev->sent_cmd && ++ hci_opcode_ogf(hci_skb_opcode(hdev->sent_cmd)) != 0x08 && ++ hci_skb_event(hdev->sent_cmd) == event) { ++ hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->sent_cmd), + status, &req_complete, &req_complete_skb); + req_evt = event; + } +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -31,10 +31,6 @@ static void hci_cmd_sync_complete(struct + hdev->req_result = result; + hdev->req_status = HCI_REQ_DONE; + +- /* Free the request command so it is not used as response */ +- kfree_skb(hdev->req_skb); +- hdev->req_skb = NULL; +- + if (skb) { + struct sock *sk = hci_skb_sk(skb); + +@@ -42,7 +38,7 @@ static void hci_cmd_sync_complete(struct + if (sk) + sock_put(sk); + +- hdev->req_rsp = skb_get(skb); ++ hdev->req_skb = skb_get(skb); + } + + wake_up_interruptible(&hdev->req_wait_q); +@@ -190,8 +186,8 @@ struct sk_buff *__hci_cmd_sync_sk(struct + + hdev->req_status = 0; + hdev->req_result = 0; +- skb = hdev->req_rsp; +- hdev->req_rsp = NULL; ++ skb = hdev->req_skb; ++ hdev->req_skb = NULL; + + bt_dev_dbg(hdev, "end: err %d", err); + +@@ -4941,11 +4937,6 @@ int hci_dev_open_sync(struct hci_dev *hd + hdev->sent_cmd = NULL; + } + +- if (hdev->req_skb) { +- kfree_skb(hdev->req_skb); +- hdev->req_skb = NULL; +- } +- + clear_bit(HCI_RUNNING, &hdev->flags); + hci_sock_dev_event(hdev, HCI_DEV_CLOSE); + +@@ -5107,12 +5098,6 @@ int hci_dev_close_sync(struct hci_dev *h + hdev->sent_cmd = NULL; + } + +- /* Drop last request */ +- if (hdev->req_skb) { +- kfree_skb(hdev->req_skb); +- hdev->req_skb = NULL; +- } +- + clear_bit(HCI_RUNNING, &hdev->flags); + hci_sock_dev_event(hdev, HCI_DEV_CLOSE); + diff --git a/queue-6.1/series b/queue-6.1/series new file mode 100644 index 00000000000..f02660b9864 --- /dev/null +++ b/queue-6.1/series @@ -0,0 +1,5 @@ +revert-bluetooth-fix-use-after-free-in-accessing-skb-after-sending-it.patch +revert-bluetooth-hci_sync-fix-overwriting-request-callback.patch +revert-bluetooth-af_bluetooth-fix-deadlock.patch +revert-bluetooth-hci_core-fix-possible-buffer-overflow.patch +revert-bluetooth-hci_conn-consolidate-code-for-aborting-connections.patch