Fix patch of CVE-2022-48878 and its pre requests and new fix patches.
Krzysztof Kozlowski (1): Bluetooth: hci_qca: Fix driver shutdown on closed serdev
Venkata Lakshmi Narayana Gubba (4): Bluetooth: hci_qca: Wait for timeout during suspend Bluetooth: hci_qca: Wait for SSR completion during suspend Bluetooth: hci_qca: check for SSR triggered flag while suspend Bluetooth: hci_qca: Fixed issue during suspend
Yang Yingliang (1): Bluetooth: hci_qca: don't call kfree_skb() under spin_lock_irqsave()
Zijun Hu (1): Bluetooth: qca: Fix BT enable failure again for QCA6390 after warm reboot
drivers/bluetooth/hci_qca.c | 82 ++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 10 deletions(-)
From: Yang Yingliang yangyingliang@huawei.com
stable inclusion from stable-v5.10.163 commit 0169acb41bc8634c50d3428edb2cae7ca304f673 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IALIJ7 CVE: CVE-2022-48878
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit df4cfc91208e0a98f078223793f5871b1a82cc54 ]
It is not allowed to call kfree_skb() from hardware interrupt context or with interrupts being disabled. So replace kfree_skb() with dev_kfree_skb_irq() under spin_lock_irqsave().
Fixes: 0ff252c1976d ("Bluetooth: hciuart: Add support QCA chipset for UART") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yuan Can yuancan@huawei.com --- drivers/bluetooth/hci_qca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index eea18aed17f8..60b0e13bb9fc 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -905,7 +905,7 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb) default: BT_ERR("Illegal tx state: %d (losing packet)", qca->tx_ibs_state); - kfree_skb(skb); + dev_kfree_skb_irq(skb); break; }
From: Venkata Lakshmi Narayana Gubba gubbaven@codeaurora.org
stable inclusion from stable-v5.10.165 commit 1ab0098333f57cc11890c07020a2e3e430000df7 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IALIJ7 CVE: CVE-2022-48878
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit 2be43abac5a839d44bf9d14716573ae0ac920f2b ]
Currently qca_suspend() is relied on IBS mechanism. During FW download and memory dump collections, IBS will be disabled. In those cases, driver will allow suspend and still uses the serdev port, which results to errors. Now added a wait timeout if suspend is triggered during FW download and memory collections.
Signed-off-by: Venkata Lakshmi Narayana Gubba gubbaven@codeaurora.org Signed-off-by: Balakrishna Godavarthi bgodavar@codeaurora.org Reviewed-by: Abhishek Pandit-Subedi abhishekpandit@chromium.org Signed-off-by: Marcel Holtmann marcel@holtmann.org Stable-dep-of: 272970be3dab ("Bluetooth: hci_qca: Fix driver shutdown on closed serdev") Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yuan Can yuancan@huawei.com --- drivers/bluetooth/hci_qca.c | 48 ++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 9 deletions(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 60b0e13bb9fc..652290425028 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -50,6 +50,8 @@ #define IBS_HOST_TX_IDLE_TIMEOUT_MS 2000 #define CMD_TRANS_TIMEOUT_MS 100 #define MEMDUMP_TIMEOUT_MS 8000 +#define IBS_DISABLE_SSR_TIMEOUT_MS (MEMDUMP_TIMEOUT_MS + 1000) +#define FW_DOWNLOAD_TIMEOUT_MS 3000
/* susclk rate */ #define SUSCLK_RATE_32KHZ 32768 @@ -68,12 +70,13 @@ #define QCA_MEMDUMP_BYTE 0xFB
enum qca_flags { - QCA_IBS_ENABLED, + QCA_IBS_DISABLED, QCA_DROP_VENDOR_EVENT, QCA_SUSPENDING, QCA_MEMDUMP_COLLECTION, QCA_HW_ERROR_EVENT, - QCA_SSR_TRIGGERED + QCA_SSR_TRIGGERED, + QCA_BT_OFF };
enum qca_capabilities { @@ -870,7 +873,7 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb) * Out-Of-Band(GPIOs control) sleep is selected. * Don't wake the device up when suspending. */ - if (!test_bit(QCA_IBS_ENABLED, &qca->flags) || + if (test_bit(QCA_IBS_DISABLED, &qca->flags) || test_bit(QCA_SUSPENDING, &qca->flags)) { skb_queue_tail(&qca->txq, skb); spin_unlock_irqrestore(&qca->hci_ibs_lock, flags); @@ -1015,7 +1018,7 @@ static void qca_controller_memdump(struct work_struct *work) * the controller to send the dump is 8 seconds. let us * start timer to handle this asynchronous activity. */ - clear_bit(QCA_IBS_ENABLED, &qca->flags); + set_bit(QCA_IBS_DISABLED, &qca->flags); set_bit(QCA_MEMDUMP_COLLECTION, &qca->flags); dump = (void *) skb->data; dump_size = __le32_to_cpu(dump->dump_size); @@ -1621,6 +1624,7 @@ static int qca_power_on(struct hci_dev *hdev) struct hci_uart *hu = hci_get_drvdata(hdev); enum qca_btsoc_type soc_type = qca_soc_type(hu); struct qca_serdev *qcadev; + struct qca_data *qca = hu->priv; int ret = 0;
/* Non-serdev device usually is powered by external power @@ -1640,6 +1644,7 @@ static int qca_power_on(struct hci_dev *hdev) } }
+ clear_bit(QCA_BT_OFF, &qca->flags); return ret; }
@@ -1659,7 +1664,7 @@ static int qca_setup(struct hci_uart *hu) return ret;
/* Patch downloading has to be done without IBS mode */ - clear_bit(QCA_IBS_ENABLED, &qca->flags); + set_bit(QCA_IBS_DISABLED, &qca->flags);
/* Enable controller to do both LE scan and BR/EDR inquiry * simultaneously. @@ -1710,7 +1715,7 @@ static int qca_setup(struct hci_uart *hu) ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver, firmware_name); if (!ret) { - set_bit(QCA_IBS_ENABLED, &qca->flags); + clear_bit(QCA_IBS_DISABLED, &qca->flags); qca_debugfs_init(hdev); hu->hdev->hw_error = qca_hw_error; hu->hdev->cmd_timeout = qca_cmd_timeout; @@ -1814,7 +1819,7 @@ static void qca_power_shutdown(struct hci_uart *hu) * data in skb's. */ spin_lock_irqsave(&qca->hci_ibs_lock, flags); - clear_bit(QCA_IBS_ENABLED, &qca->flags); + set_bit(QCA_IBS_DISABLED, &qca->flags); qca_flush(hu); spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
@@ -1833,6 +1838,8 @@ static void qca_power_shutdown(struct hci_uart *hu) } else if (qcadev->bt_en) { gpiod_set_value_cansleep(qcadev->bt_en, 0); } + + set_bit(QCA_BT_OFF, &qca->flags); }
static int qca_power_off(struct hci_dev *hdev) @@ -2093,11 +2100,34 @@ static int __maybe_unused qca_suspend(struct device *dev) bool tx_pending = false; int ret = 0; u8 cmd; + u32 wait_timeout = 0;
set_bit(QCA_SUSPENDING, &qca->flags);
- /* Device is downloading patch or doesn't support in-band sleep. */ - if (!test_bit(QCA_IBS_ENABLED, &qca->flags)) + if (test_bit(QCA_BT_OFF, &qca->flags)) + return 0; + + if (test_bit(QCA_IBS_DISABLED, &qca->flags)) { + wait_timeout = test_bit(QCA_SSR_TRIGGERED, &qca->flags) ? + IBS_DISABLE_SSR_TIMEOUT_MS : + FW_DOWNLOAD_TIMEOUT_MS; + + /* QCA_IBS_DISABLED flag is set to true, During FW download + * and during memory dump collection. It is reset to false, + * After FW download complete and after memory dump collections. + */ + wait_on_bit_timeout(&qca->flags, QCA_IBS_DISABLED, + TASK_UNINTERRUPTIBLE, msecs_to_jiffies(wait_timeout)); + + if (test_bit(QCA_IBS_DISABLED, &qca->flags)) { + bt_dev_err(hu->hdev, "SSR or FW download time out"); + ret = -ETIMEDOUT; + goto error; + } + } + + /* After memory dump collection, Controller is powered off.*/ + if (test_bit(QCA_BT_OFF, &qca->flags)) return 0;
cancel_work_sync(&qca->ws_awake_device);
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
stable inclusion from stable-v5.10.165 commit e84ec6e25df9bb0968599e92eacedaf3a0a5b587 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IALIJ7 CVE: CVE-2022-48878
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit 272970be3dabd24cbe50e393ffee8f04aec3b9a8 ]
The driver shutdown callback (which sends EDL_SOC_RESET to the device over serdev) should not be invoked when HCI device is not open (e.g. if hci_dev_open_sync() failed), because the serdev and its TTY are not open either. Also skip this step if device is powered off (qca_power_shutdown()).
The shutdown callback causes use-after-free during system reboot with Qualcomm Atheros Bluetooth:
Unable to handle kernel paging request at virtual address 0072662f67726fd7 ... CPU: 6 PID: 1 Comm: systemd-shutdow Tainted: G W 6.1.0-rt5-00325-g8a5f56bcfcca #8 Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) Call trace: tty_driver_flush_buffer+0x4/0x30 serdev_device_write_flush+0x24/0x34 qca_serdev_shutdown+0x80/0x130 [hci_uart] device_shutdown+0x15c/0x260 kernel_restart+0x48/0xac
KASAN report:
BUG: KASAN: use-after-free in tty_driver_flush_buffer+0x1c/0x50 Read of size 8 at addr ffff16270c2e0018 by task systemd-shutdow/1
CPU: 7 PID: 1 Comm: systemd-shutdow Not tainted 6.1.0-next-20221220-00014-gb85aaf97fb01-dirty #28 Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) Call trace: dump_backtrace.part.0+0xdc/0xf0 show_stack+0x18/0x30 dump_stack_lvl+0x68/0x84 print_report+0x188/0x488 kasan_report+0xa4/0xf0 __asan_load8+0x80/0xac tty_driver_flush_buffer+0x1c/0x50 ttyport_write_flush+0x34/0x44 serdev_device_write_flush+0x48/0x60 qca_serdev_shutdown+0x124/0x274 device_shutdown+0x1e8/0x350 kernel_restart+0x48/0xb0 __do_sys_reboot+0x244/0x2d0 __arm64_sys_reboot+0x54/0x70 invoke_syscall+0x60/0x190 el0_svc_common.constprop.0+0x7c/0x160 do_el0_svc+0x44/0xf0 el0_svc+0x2c/0x6c el0t_64_sync_handler+0xbc/0x140 el0t_64_sync+0x190/0x194
Fixes: 7e7bbddd029b ("Bluetooth: hci_qca: Fix qca6390 enable failure after warm reboot") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yuan Can yuancan@huawei.com --- drivers/bluetooth/hci_qca.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 652290425028..096a604ef47f 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -2064,10 +2064,17 @@ static void qca_serdev_shutdown(struct device *dev) int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS); struct serdev_device *serdev = to_serdev_device(dev); struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); + struct hci_uart *hu = &qcadev->serdev_hu; + struct hci_dev *hdev = hu->hdev; + struct qca_data *qca = hu->priv; const u8 ibs_wake_cmd[] = { 0xFD }; const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 };
if (qcadev->btsoc_type == QCA_QCA6390) { + if (test_bit(QCA_BT_OFF, &qca->flags) || + !test_bit(HCI_RUNNING, &hdev->flags)) + return; + serdev_device_write_flush(serdev); ret = serdev_device_write_buf(serdev, ibs_wake_cmd, sizeof(ibs_wake_cmd));
From: Venkata Lakshmi Narayana Gubba gubbaven@codeaurora.org
stable inclusion from stable-v5.10.165 commit ef11bc4bb9757a5ee3ded5b8d8f7652fa0d079c0 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IALIJ7 CVE: CVE-2022-48878
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit ad3a9c0ec2d2baed936cfdd05870f9d1e1f40e0e upstream.
During SSR after memory dump collection,BT controller will be powered off, powered on and then FW will be downloaded.During suspend if BT controller is powered off due to SSR then we should wait until SSR is completed and then suspend.
Fixes: 2be43abac5a8 ("Bluetooth: hci_qca: Wait for timeout during suspend") Signed-off-by: Venkata Lakshmi Narayana Gubba gubbaven@codeaurora.org Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yuan Can yuancan@huawei.com --- drivers/bluetooth/hci_qca.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 096a604ef47f..ac58100dd824 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -50,7 +50,8 @@ #define IBS_HOST_TX_IDLE_TIMEOUT_MS 2000 #define CMD_TRANS_TIMEOUT_MS 100 #define MEMDUMP_TIMEOUT_MS 8000 -#define IBS_DISABLE_SSR_TIMEOUT_MS (MEMDUMP_TIMEOUT_MS + 1000) +#define IBS_DISABLE_SSR_TIMEOUT_MS \ + (MEMDUMP_TIMEOUT_MS + FW_DOWNLOAD_TIMEOUT_MS) #define FW_DOWNLOAD_TIMEOUT_MS 3000
/* susclk rate */ @@ -2111,7 +2112,12 @@ static int __maybe_unused qca_suspend(struct device *dev)
set_bit(QCA_SUSPENDING, &qca->flags);
- if (test_bit(QCA_BT_OFF, &qca->flags)) + /* During SSR after memory dump collection, controller will be + * powered off and then powered on.If controller is powered off + * during SSR then we should wait until SSR is completed. + */ + if (test_bit(QCA_BT_OFF, &qca->flags) && + !test_bit(QCA_SSR_TRIGGERED, &qca->flags)) return 0;
if (test_bit(QCA_IBS_DISABLED, &qca->flags)) { @@ -2121,7 +2127,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
/* QCA_IBS_DISABLED flag is set to true, During FW download * and during memory dump collection. It is reset to false, - * After FW download complete and after memory dump collections. + * After FW download complete. */ wait_on_bit_timeout(&qca->flags, QCA_IBS_DISABLED, TASK_UNINTERRUPTIBLE, msecs_to_jiffies(wait_timeout)); @@ -2133,10 +2139,6 @@ static int __maybe_unused qca_suspend(struct device *dev) } }
- /* After memory dump collection, Controller is powered off.*/ - if (test_bit(QCA_BT_OFF, &qca->flags)) - return 0; - cancel_work_sync(&qca->ws_awake_device); cancel_work_sync(&qca->ws_awake_rx);
From: Venkata Lakshmi Narayana Gubba gubbaven@codeaurora.org
stable inclusion from stable-v5.10.165 commit c208f1e84a6757c42a954a6c161e65c2608f11e3 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IALIJ7 CVE: CVE-2022-48878
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit 1bb0c66332babc5cbc4581d962da0b03af9f23e8 upstream.
QCA_IBS_DISABLED flag will be set after memorydump started from controller.Currently qca_suspend() is waiting for SSR to complete based on flag QCA_IBS_DISABLED.Added to check for QCA_SSR_TRIGGERED flag too.
Fixes: 2be43abac5a8 ("Bluetooth: hci_qca: Wait for timeout during suspend") Signed-off-by: Venkata Lakshmi Narayana Gubba gubbaven@codeaurora.org Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yuan Can yuancan@huawei.com --- drivers/bluetooth/hci_qca.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index ac58100dd824..3c945b12028e 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -2120,7 +2120,8 @@ static int __maybe_unused qca_suspend(struct device *dev) !test_bit(QCA_SSR_TRIGGERED, &qca->flags)) return 0;
- if (test_bit(QCA_IBS_DISABLED, &qca->flags)) { + if (test_bit(QCA_IBS_DISABLED, &qca->flags) || + test_bit(QCA_SSR_TRIGGERED, &qca->flags)) { wait_timeout = test_bit(QCA_SSR_TRIGGERED, &qca->flags) ? IBS_DISABLE_SSR_TIMEOUT_MS : FW_DOWNLOAD_TIMEOUT_MS;
From: Venkata Lakshmi Narayana Gubba gubbaven@codeaurora.org
stable inclusion from stable-v5.10.165 commit 217721b7631348ff89825ea56a33235edef79f51 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IALIJ7 CVE: CVE-2022-48878
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit 55c0bd77479b60ea29fd390faf4545cfb3a1d79e upstream.
If BT SoC is running with ROM FW then just return in qca_suspend function as ROM FW does not support in-band sleep.
Fixes: 2be43abac5a8 ("Bluetooth: hci_qca: Wait for timeout during suspend") Signed-off-by: Venkata Lakshmi Narayana Gubba gubbaven@codeaurora.org Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Yuan Can yuancan@huawei.com --- drivers/bluetooth/hci_qca.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 3c945b12028e..5347fc465ce8 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -77,7 +77,8 @@ enum qca_flags { QCA_MEMDUMP_COLLECTION, QCA_HW_ERROR_EVENT, QCA_SSR_TRIGGERED, - QCA_BT_OFF + QCA_BT_OFF, + QCA_ROM_FW };
enum qca_capabilities { @@ -1664,6 +1665,7 @@ static int qca_setup(struct hci_uart *hu) if (ret) return ret;
+ clear_bit(QCA_ROM_FW, &qca->flags); /* Patch downloading has to be done without IBS mode */ set_bit(QCA_IBS_DISABLED, &qca->flags);
@@ -1722,12 +1724,14 @@ static int qca_setup(struct hci_uart *hu) hu->hdev->cmd_timeout = qca_cmd_timeout; } else if (ret == -ENOENT) { /* No patch/nvm-config found, run with original fw/config */ + set_bit(QCA_ROM_FW, &qca->flags); ret = 0; } else if (ret == -EAGAIN) { /* * Userspace firmware loader will return -EAGAIN in case no * patch/nvm-config is found, so run with original fw/config. */ + set_bit(QCA_ROM_FW, &qca->flags); ret = 0; } else { if (retries < MAX_INIT_RETRIES) { @@ -2112,6 +2116,12 @@ static int __maybe_unused qca_suspend(struct device *dev)
set_bit(QCA_SUSPENDING, &qca->flags);
+ /* if BT SoC is running with default firmware then it does not + * support in-band sleep + */ + if (test_bit(QCA_ROM_FW, &qca->flags)) + return 0; + /* During SSR after memory dump collection, controller will be * powered off and then powered on.If controller is powered off * during SSR then we should wait until SSR is completed.
From: Zijun Hu quic_zijuhu@quicinc.com
stable inclusion from stable-v5.10.222 commit 215a26c2404fa34625c725d446967fa328a703eb category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IALIJ7 CVE: CVE-2022-48878
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit 88e72239ead9814b886db54fc4ee39ef3c2b8f26 upstream.
Commit 272970be3dab ("Bluetooth: hci_qca: Fix driver shutdown on closed serdev") will cause below regression issue:
BT can't be enabled after below steps: cold boot -> enable BT -> disable BT -> warm reboot -> BT enable failure if property enable-gpios is not configured within DT|ACPI for QCA6390.
The commit is to fix a use-after-free issue within qca_serdev_shutdown() by adding condition to avoid the serdev is flushed or wrote after closed but also introduces this regression issue regarding above steps since the VSC is not sent to reset controller during warm reboot.
Fixed by sending the VSC to reset controller within qca_serdev_shutdown() once BT was ever enabled, and the use-after-free issue is also fixed by this change since the serdev is still opened before it is flushed or wrote.
Verified by the reported machine Dell XPS 13 9310 laptop over below two kernel commits: commit e00fc2700a3f ("Bluetooth: btusb: Fix triggering coredump implementation for QCA") of bluetooth-next tree. commit b23d98d46d28 ("Bluetooth: btusb: Fix triggering coredump implementation for QCA") of linus mainline tree.
Fixes: 272970be3dab ("Bluetooth: hci_qca: Fix driver shutdown on closed serdev") Cc: stable@vger.kernel.org Reported-by: Wren Turkal wt@penguintechs.org Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218726 Signed-off-by: Zijun Hu quic_zijuhu@quicinc.com Tested-by: Wren Turkal wt@penguintechs.org Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yuan Can yuancan@huawei.com --- drivers/bluetooth/hci_qca.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 5347fc465ce8..ffbb34770b9b 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -2071,15 +2071,27 @@ static void qca_serdev_shutdown(struct device *dev) struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); struct hci_uart *hu = &qcadev->serdev_hu; struct hci_dev *hdev = hu->hdev; - struct qca_data *qca = hu->priv; const u8 ibs_wake_cmd[] = { 0xFD }; const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 };
if (qcadev->btsoc_type == QCA_QCA6390) { - if (test_bit(QCA_BT_OFF, &qca->flags) || - !test_bit(HCI_RUNNING, &hdev->flags)) + /* The purpose of sending the VSC is to reset SOC into a initial + * state and the state will ensure next hdev->setup() success. + * if HCI_QUIRK_NON_PERSISTENT_SETUP is set, it means that + * hdev->setup() can do its job regardless of SoC state, so + * don't need to send the VSC. + * if HCI_SETUP is set, it means that hdev->setup() was never + * invoked and the SOC is already in the initial state, so + * don't also need to send the VSC. + */ + if (test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks) || + hci_dev_test_flag(hdev, HCI_SETUP)) return;
+ /* The serdev must be in open state when conrol logic arrives + * here, so also fix the use-after-free issue caused by that + * the serdev is flushed or wrote after it is closed. + */ serdev_device_write_flush(serdev); ret = serdev_device_write_buf(serdev, ibs_wake_cmd, sizeof(ibs_wake_cmd));
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/13247 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/U...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/13247 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/U...