Fix patch of CVE-2022-48878 and its pre requests.
Krzysztof Kozlowski (1): Bluetooth: hci_qca: Fix driver shutdown on closed serdev
Venkata Lakshmi Narayana Gubba (1): Bluetooth: hci_qca: Wait for timeout during suspend
Yang Yingliang (1): Bluetooth: hci_qca: don't call kfree_skb() under spin_lock_irqsave()
drivers/bluetooth/hci_qca.c | 57 ++++++++++++++++++++++++++++++------- 1 file changed, 47 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));
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/11902 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/Y...
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/11902 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/Y...