FAILED: patch "[PATCH] Bluetooth: btusb: fix use-after-free on marvell probe failure" failed to apply to 5.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.10-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.10.y
git checkout FETCH_HEAD
git cherry-pick -x c5b600a3c05b1a7a110d558df935a8fc8a471c79
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026071309-contempt-purposely-3c5c@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From c5b600a3c05b1a7a110d558df935a8fc8a471c79 Mon Sep 17 00:00:00 2001
From: Johan Hovold <[email protected]>
Date: Thu, 4 Jun 2026 08:37:37 +0200
Subject: [PATCH] Bluetooth: btusb: fix use-after-free on marvell probe failure
Make sure to stop any TX URBs submitted during Marvell OOB wakeup configuration on later probe failures to avoid use-after-free in the completion callback.
This issue was reported by Sashiko while reviewing a fix for a wakeup source leak in the btusb probe errors paths.
drivers/bluetooth/btusb.c +5 -3
@@ -4237,7 +4237,7 @@ static int btusb_probe(struct usb_interface *intf,if (id->driver_info &BTUSB_INTEL_COMBINED ) { err =btintel_configure_setup (hdev, btusb_driver.name);if (err) - goto out_free_dev; + goto err_kill_tx_urbs;/* Transport specific configuration */ hdev->send = btusb_send_frame_intel;
@@ -4401,7 +4401,7 @@ static int btusb_probe(struct usb_interface *intf, err =usb_set_interface (data->udev,0 ,0 );if (err <0 ) {BT_ERR ("failed to set interface 0, alt 0 %d" , err); - goto out_free_dev; + goto err_kill_tx_urbs; } }
@@ -4409,7 +4409,7 @@ static int btusb_probe(struct usb_interface *intf, err =usb_driver_claim_interface (&btusb_driver, data->isoc, data);if (err <0 ) - goto out_free_dev; + goto err_kill_tx_urbs; }if (IS_ENABLED (CONFIG_BT_HCIBTUSB_BCM ) && data->diag) {
@@ -4445,6 +4445,8 @@ static int btusb_probe(struct usb_interface *intf,usb_set_intfdata (data->isoc,NULL );usb_driver_release_interface (&btusb_driver, data->isoc); } +err_kill_tx_urbs: +usb_kill_anchored_urbs (&data->tx_anchor); out_free_dev:if (data->reset_gpio)gpiod_put (data->reset_gpio);
Sasha Levin
maintainerPATCH 1/4 Bluetooth: btintel: Fix offset calculation boot address parameter
From: Kiran K <[email protected]>
[ Upstream commit d00745da644d42c2f97293eb3fe19cfd5c0b073c ]
Boot address parameter was not getting updated properly due to wrong offset
Stable-dep-of: c5b600a3c05b ("Bluetooth: btusb: fix use-after-free on marvell probe failure")
--- drivers/bluetooth/btintel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/bluetooth/btintel.c +2 -1
@@ -863,7 +863,8 @@ static int btintel_download_firmware_payload(struct hci_dev *hdev,/* The boot parameter is the first 32-bit value * and rest of 3 octets are reserved. */ - *boot_param =get_unaligned_le32 (fw_ptr +sizeof (*cmd)); + *boot_param =get_unaligned_le32 (fw_ptr + frag_len + +sizeof (*cmd));bt_dev_dbg (hdev,"boot_param=0x%x" , *boot_param); }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/4 Bluetooth: btintel: Check firmware version before download
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit ac0565462e330a2b762ca5849a4140b29d725786 ]
This checks the firmware build number, week and year against the repective loaded version. If details are a match, skip the download process.
Stable-dep-of: c5b600a3c05b ("Bluetooth: btusb: fix use-after-free on marvell probe failure")
--- drivers/bluetooth/btintel.c | 106 +++++++++++++++++++++++++++------- drivers/bluetooth/btintel.h | 5 +- drivers/bluetooth/btusb.c | 9 ++- drivers/bluetooth/hci_intel.c | 7 ++- 4 files changed, 101 insertions(+), 26 deletions(-)
drivers/bluetooth/btintel.c +85 -21
@@ -24,6 +24,14 @@#define ECDSA_OFFSET 644#define ECDSA_HEADER_LEN 320 +#define CMD_WRITE_BOOT_PARAMS 0xfc0e +struct cmd_write_boot_params { +u32 boot_addr; +u8 fw_build_num; +u8 fw_build_ww; +u8 fw_build_yy; +} __packed; +int btintel_check_bdaddr (struct hci_dev *hdev) {struct hci_rp_read_bd_addr *bda;
@@ -841,7 +849,7 @@ static int btintel_sfi_ecdsa_header_secure_send(struct hci_dev *hdev,static int btintel_download_firmware_payload (struct hci_dev *hdev,const struct firmware *fw, -u32 *boot_param,size_t offset) +size_t offset) {int err;const u8 *fw_ptr;
@@ -854,21 +862,6 @@ static int btintel_download_firmware_payload(struct hci_dev *hdev,while (fw_ptr - fw->data < fw->size) {struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len); -/* Each SKU has a different reset parameter to use in the -* HCI_Intel_Reset command and it is embedded in the firmware -* data. So, instead of using static value per SKU, check -* the firmware data and save it for later use. -*/ -if (le16_to_cpu (cmd->opcode) ==0xfc0e ) { -/* The boot parameter is the first 32-bit value -* and rest of 3 octets are reserved. -*/ - *boot_param =get_unaligned_le32 (fw_ptr + frag_len + -sizeof (*cmd)); - -bt_dev_dbg (hdev,"boot_param=0x%x" , *boot_param); - } - frag_len +=sizeof (*cmd) + cmd->plen;/* The parameter length of the secure send command requires
@@ -897,28 +890,101 @@ static int btintel_download_firmware_payload(struct hci_dev *hdev,return err; } +static bool btintel_firmware_version (struct hci_dev *hdev, +u8 num,u8 ww,u8 yy, +const struct firmware *fw, +u32 *boot_addr) +{ +const u8 *fw_ptr; + + fw_ptr = fw->data; + +while (fw_ptr - fw->data < fw->size) { +struct hci_command_hdr *cmd = (void *)(fw_ptr); + +/* Each SKU has a different reset parameter to use in the +* HCI_Intel_Reset command and it is embedded in the firmware +* data. So, instead of using static value per SKU, check +* the firmware data and save it for later use. +*/ +if (le16_to_cpu (cmd->opcode) ==CMD_WRITE_BOOT_PARAMS ) { +struct cmd_write_boot_params *params; + + params = (void *)(fw_ptr +sizeof (*cmd)); + +bt_dev_info (hdev,"Boot Address: 0x%x" , +le32_to_cpu (params->boot_addr)); + +bt_dev_info (hdev,"Firmware Version: %u-%u.%u" , + params->fw_build_num, params->fw_build_ww, + params->fw_build_yy); + +return (num == params->fw_build_num && + ww == params->fw_build_ww && + yy == params->fw_build_yy); + } + + fw_ptr +=sizeof (*cmd) + cmd->plen; + } + +return false; +} +int btintel_download_firmware (struct hci_dev *hdev, +struct intel_version *ver,const struct firmware *fw,u32 *boot_param) {int err; +/* SfP and WsP don't seem to update the firmware version on file +* so version checking is currently not possible. +*/ +switch (ver->hw_variant) { +case 0x0b :/* SfP */ +case 0x0c :/* WsP */ +/* Skip version checking */ +break ; +default : +/* Skip download if firmware has the same version */ +if (btintel_firmware_version (hdev, ver->fw_build_num, + ver->fw_build_ww, ver->fw_build_yy, + fw, boot_param)) { +bt_dev_info (hdev,"Firmware already loaded" ); +/* Return -EALREADY to indicate that the firmware has +* already been loaded. +*/ +return -EALREADY ; + } + } + err =btintel_sfi_rsa_header_secure_send (hdev, fw);if (err)return err; -return btintel_download_firmware_payload (hdev, fw, boot_param, -RSA_HEADER_LEN ); +return btintel_download_firmware_payload (hdev, fw,RSA_HEADER_LEN ); }EXPORT_SYMBOL_GPL (btintel_download_firmware);int btintel_download_firmware_newgen (struct hci_dev *hdev, +struct intel_version_tlv *ver,const struct firmware *fw,u32 *boot_param,u8 hw_variant,u8 sbe_type) {int err;u32 css_header_ver; +/* Skip download if firmware has the same version */ +if (btintel_firmware_version (hdev, ver->min_fw_build_nn, + ver->min_fw_build_cw, ver->min_fw_build_yy, + fw, boot_param)) { +bt_dev_info (hdev,"Firmware already loaded" ); +/* Return -EALREADY to indicate that firmware has already been +* loaded. +*/ +return -EALREADY ; + } +/* iBT hardware variants 0x0b, 0x0c, 0x11, 0x12, 0x13, 0x14 support * only RSA secure boot engine. Hence, the corresponding sfi file will * have RSA header of 644 bytes followed by Command Buffer.
@@ -948,7 +1014,7 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev,if (err)return err; - err =btintel_download_firmware_payload (hdev, fw, boot_param,RSA_HEADER_LEN ); + err =btintel_download_firmware_payload (hdev, fw,RSA_HEADER_LEN );if (err)return err; }else if (hw_variant >=0x17 ) {
@@ -969,7 +1035,6 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev,return err; err =btintel_download_firmware_payload (hdev, fw, - boot_param,RSA_HEADER_LEN +ECDSA_HEADER_LEN );if (err)return err;
@@ -979,7 +1044,6 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev,return err; err =btintel_download_firmware_payload (hdev, fw, - boot_param,RSA_HEADER_LEN +ECDSA_HEADER_LEN );if (err)return err;
drivers/bluetooth/btintel.h +3 -2
@@ -157,9 +157,10 @@ struct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read,int btintel_send_intel_reset (struct hci_dev *hdev,u32 boot_param);int btintel_read_boot_params (struct hci_dev *hdev,struct intel_boot_params *params); -int btintel_download_firmware (struct hci_dev *dev,const struct firmware *fw, -u32 *boot_param); +int btintel_download_firmware (struct hci_dev *dev,struct intel_version *ver, +const struct firmware *fw,u32 *boot_param);int btintel_download_firmware_newgen (struct hci_dev *hdev, +struct intel_version_tlv *ver,const struct firmware *fw,u32 *boot_param,u8 hw_variant,u8 sbe_type);
drivers/bluetooth/btusb.c +8 -1
@@ -2602,8 +2602,15 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,set_bit (BTUSB_DOWNLOADING , &data->flags);/* Start firmware downloading and get boot parameter */ - err =btintel_download_firmware (hdev, fw, boot_param); + err =btintel_download_firmware (hdev, ver, fw, boot_param);if (err <0 ) { +if (err == -EALREADY ) { +/* Firmware has already been loaded */ +set_bit (BTUSB_FIRMWARE_LOADED , &data->flags); + err =0 ; + goto done; + } +/* When FW download fails, send Intel Reset to retry * FW download. */
drivers/bluetooth/hci_intel.c +5 -2
@@ -735,7 +735,7 @@ static int intel_setup(struct hci_uart *hu)set_bit (STATE_DOWNLOADING , &intel->flags);/* Start firmware downloading and get boot parameter */ - err =btintel_download_firmware (hdev, fw, &boot_param); + err =btintel_download_firmware (hdev, &ver, fw, &boot_param);if (err <0 ) goto done;
@@ -784,7 +784,10 @@ static int intel_setup(struct hci_uart *hu) done:release_firmware (fw); -if (err <0 ) +/* Check if there was an error and if is not -EALREADY which means the +* firmware has already been loaded. +*/ +if (err <0 && err != -EALREADY )return err;/* We need to restore the default speed before Intel reset */
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/4 Bluetooth: btusb: fix use-after-free on registration failure
In reply to Sasha LevinFrom: Johan Hovold <[email protected]>
[ Upstream commit eedc6867ebad73edbfaf9a0a65fbef7115cc4753 ]
Make sure to release the sibling interfaces in case controller registration fails to avoid use-after-free and double-free when they are eventually disconnected.
This issue was reported by Sashiko while reviewing a fix for a wakeup source leak in the btusb probe errors paths.
Stable-dep-of: c5b600a3c05b ("Bluetooth: btusb: fix use-after-free on marvell probe failure")
--- drivers/bluetooth/btusb.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/bluetooth/btusb.c +10 -1
@@ -4376,12 +4376,21 @@ static int btusb_probe(struct usb_interface *intf, err =hci_register_dev (hdev);if (err <0 ) - goto out_free_dev; + goto err_release_siblings;usb_set_intfdata (intf, data);return 0 ; +err_release_siblings: +if (data->diag) { +usb_set_intfdata (data->diag,NULL ); +usb_driver_release_interface (&btusb_driver, data->diag); + } +if (data->isoc) { +usb_set_intfdata (data->isoc,NULL ); +usb_driver_release_interface (&btusb_driver, data->isoc); + } out_free_dev:if (data->reset_gpio)gpiod_put (data->reset_gpio);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 4/4 Bluetooth: btusb: fix use-after-free on marvell probe failure
In reply to Sasha LevinFrom: Johan Hovold <[email protected]>
[ Upstream commit c5b600a3c05b1a7a110d558df935a8fc8a471c79 ]
Make sure to stop any TX URBs submitted during Marvell OOB wakeup configuration on later probe failures to avoid use-after-free in the completion callback.
This issue was reported by Sashiko while reviewing a fix for a wakeup source leak in the btusb probe errors paths.
--- drivers/bluetooth/btusb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/bluetooth/btusb.c +4 -2
@@ -4352,7 +4352,7 @@ static int btusb_probe(struct usb_interface *intf, err =usb_set_interface (data->udev,0 ,0 );if (err <0 ) {BT_ERR ("failed to set interface 0, alt 0 %d" , err); - goto out_free_dev; + goto err_kill_tx_urbs; } }
@@ -4360,7 +4360,7 @@ static int btusb_probe(struct usb_interface *intf, err =usb_driver_claim_interface (&btusb_driver, data->isoc, data);if (err <0 ) - goto out_free_dev; + goto err_kill_tx_urbs; }if (IS_ENABLED (CONFIG_BT_HCIBTUSB_BCM ) && data->diag) {
@@ -4391,6 +4391,8 @@ static int btusb_probe(struct usb_interface *intf,usb_set_intfdata (data->isoc,NULL );usb_driver_release_interface (&btusb_driver, data->isoc); } +err_kill_tx_urbs: +usb_kill_anchored_urbs (&data->tx_anchor); out_free_dev:if (data->reset_gpio)gpiod_put (data->reset_gpio);
Signature · 1 line
2.53.0