Unverified Commit 9c5b52f1 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!13247 CVE-2022-48878

Merge Pull Request from: @ci-robot 
 
PR sync from: Yuan Can <yuancan@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/UELTJ2JVQNUB6CVE4G33YJXG32QMR5QZ/ 
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


-- 
2.17.1
 
https://gitee.com/src-openeuler/kernel/issues/IALIJ7 
 
Link:https://gitee.com/openeuler/kernel/pulls/13247

 

Reviewed-by: default avatarYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parents 81876e0e 39a26aab
Loading
Loading
Loading
Loading
+72 −10
Original line number Diff line number Diff line
@@ -50,6 +50,9 @@
#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 + FW_DOWNLOAD_TIMEOUT_MS)
#define FW_DOWNLOAD_TIMEOUT_MS		3000

/* susclk rate */
#define SUSCLK_RATE_32KHZ	32768
@@ -68,12 +71,14 @@
#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,
	QCA_ROM_FW
};

enum qca_capabilities {
@@ -870,7 +875,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);
@@ -905,7 +910,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;
	}

@@ -1015,7 +1020,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 +1626,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 +1646,7 @@ static int qca_power_on(struct hci_dev *hdev)
		}
	}

	clear_bit(QCA_BT_OFF, &qca->flags);
	return ret;
}

@@ -1658,8 +1665,9 @@ 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 */
	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,18 +1718,20 @@ 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;
	} 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) {
@@ -1814,7 +1824,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 +1843,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)
@@ -2057,10 +2069,29 @@ 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;
	const u8 ibs_wake_cmd[] = { 0xFD };
	const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 };

	if (qcadev->btsoc_type == QCA_QCA6390) {
		/* 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));
@@ -2093,13 +2124,44 @@ 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 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.
	 */
	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) ||
	    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;

		/* 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.
		 */
		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;
		}
	}

	cancel_work_sync(&qca->ws_awake_device);
	cancel_work_sync(&qca->ws_awake_rx);