From c96fe77fd166d373cf04aa3278e90036bb25fd12 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 13 May 2024 17:36:04 +0200 Subject: [PATCH] 5.15-stable patches added patches: bluetooth-qca-add-missing-firmware-sanity-checks.patch bluetooth-qca-fix-firmware-check-error-path.patch bluetooth-qca-fix-nvm-configuration-parsing.patch --- ...a-add-missing-firmware-sanity-checks.patch | 135 ++++++++++++++++++ ...th-qca-fix-firmware-check-error-path.patch | 35 +++++ ...th-qca-fix-nvm-configuration-parsing.patch | 91 ++++++++++++ queue-5.15/series | 3 + 4 files changed, 264 insertions(+) create mode 100644 queue-5.15/bluetooth-qca-add-missing-firmware-sanity-checks.patch create mode 100644 queue-5.15/bluetooth-qca-fix-firmware-check-error-path.patch create mode 100644 queue-5.15/bluetooth-qca-fix-nvm-configuration-parsing.patch diff --git a/queue-5.15/bluetooth-qca-add-missing-firmware-sanity-checks.patch b/queue-5.15/bluetooth-qca-add-missing-firmware-sanity-checks.patch new file mode 100644 index 00000000000..a30a80fe405 --- /dev/null +++ b/queue-5.15/bluetooth-qca-add-missing-firmware-sanity-checks.patch @@ -0,0 +1,135 @@ +From 2e4edfa1e2bd821a317e7d006517dcf2f3fac68d Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 30 Apr 2024 19:07:39 +0200 +Subject: Bluetooth: qca: add missing firmware sanity checks + +From: Johan Hovold + +commit 2e4edfa1e2bd821a317e7d006517dcf2f3fac68d upstream. + +Add the missing sanity checks when parsing the firmware files before +downloading them to avoid accessing and corrupting memory beyond the +vmalloced buffer. + +Fixes: 83e81961ff7e ("Bluetooth: btqca: Introduce generic QCA ROME support") +Cc: stable@vger.kernel.org # 4.10 +Signed-off-by: Johan Hovold +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/btqca.c | 38 ++++++++++++++++++++++++++++++++------ + 1 file changed, 32 insertions(+), 6 deletions(-) + +--- a/drivers/bluetooth/btqca.c ++++ b/drivers/bluetooth/btqca.c +@@ -182,9 +182,10 @@ int qca_send_pre_shutdown_cmd(struct hci + } + EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); + +-static void qca_tlv_check_data(struct hci_dev *hdev, ++static int qca_tlv_check_data(struct hci_dev *hdev, + struct qca_fw_config *config, +- u8 *fw_data, enum qca_btsoc_type soc_type) ++ u8 *fw_data, size_t fw_size, ++ enum qca_btsoc_type soc_type) + { + const u8 *data; + u32 type_len; +@@ -200,6 +201,9 @@ static void qca_tlv_check_data(struct hc + + switch (config->type) { + case ELF_TYPE_PATCH: ++ if (fw_size < 7) ++ return -EINVAL; ++ + config->dnld_mode = QCA_SKIP_EVT_VSE_CC; + config->dnld_type = QCA_SKIP_EVT_VSE_CC; + +@@ -208,6 +212,9 @@ static void qca_tlv_check_data(struct hc + bt_dev_dbg(hdev, "File version : 0x%x", fw_data[6]); + break; + case TLV_TYPE_PATCH: ++ if (fw_size < sizeof(struct tlv_type_hdr) + sizeof(struct tlv_type_patch)) ++ return -EINVAL; ++ + tlv = (struct tlv_type_hdr *)fw_data; + type_len = le32_to_cpu(tlv->type_len); + tlv_patch = (struct tlv_type_patch *)tlv->data; +@@ -247,6 +254,9 @@ static void qca_tlv_check_data(struct hc + break; + + case TLV_TYPE_NVM: ++ if (fw_size < sizeof(struct tlv_type_hdr)) ++ return -EINVAL; ++ + tlv = (struct tlv_type_hdr *)fw_data; + + type_len = le32_to_cpu(tlv->type_len); +@@ -255,17 +265,26 @@ static void qca_tlv_check_data(struct hc + BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff); + BT_DBG("Length\t\t : %d bytes", length); + ++ if (fw_size < length + (tlv->data - fw_data)) ++ return -EINVAL; ++ + idx = 0; + data = tlv->data; +- while (idx < length) { ++ while (idx < length - sizeof(struct tlv_type_nvm)) { + tlv_nvm = (struct tlv_type_nvm *)(data + idx); + + tag_id = le16_to_cpu(tlv_nvm->tag_id); + tag_len = le16_to_cpu(tlv_nvm->tag_len); + ++ if (length < idx + sizeof(struct tlv_type_nvm) + tag_len) ++ return -EINVAL; ++ + /* Update NVM tags as needed */ + switch (tag_id) { + case EDL_TAG_ID_HCI: ++ if (tag_len < 3) ++ return -EINVAL; ++ + /* HCI transport layer parameters + * enabling software inband sleep + * onto controller side. +@@ -281,6 +300,9 @@ static void qca_tlv_check_data(struct hc + break; + + case EDL_TAG_ID_DEEP_SLEEP: ++ if (tag_len < 1) ++ return -EINVAL; ++ + /* Sleep enable mask + * enabling deep sleep feature on controller. + */ +@@ -289,14 +311,16 @@ static void qca_tlv_check_data(struct hc + break; + } + +- idx += (sizeof(u16) + sizeof(u16) + 8 + tag_len); ++ idx += sizeof(struct tlv_type_nvm) + tag_len; + } + break; + + default: + BT_ERR("Unknown TLV type %d", config->type); +- break; ++ return -EINVAL; + } ++ ++ return 0; + } + + static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, +@@ -446,7 +470,9 @@ static int qca_download_firmware(struct + memcpy(data, fw->data, size); + release_firmware(fw); + +- qca_tlv_check_data(hdev, config, data, soc_type); ++ ret = qca_tlv_check_data(hdev, config, data, size, soc_type); ++ if (ret) ++ return ret; + + segment = data; + remain = size; diff --git a/queue-5.15/bluetooth-qca-fix-firmware-check-error-path.patch b/queue-5.15/bluetooth-qca-fix-firmware-check-error-path.patch new file mode 100644 index 00000000000..ad976f83a97 --- /dev/null +++ b/queue-5.15/bluetooth-qca-fix-firmware-check-error-path.patch @@ -0,0 +1,35 @@ +From 40d442f969fb1e871da6fca73d3f8aef1f888558 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 1 May 2024 08:37:40 +0200 +Subject: Bluetooth: qca: fix firmware check error path + +From: Johan Hovold + +commit 40d442f969fb1e871da6fca73d3f8aef1f888558 upstream. + +A recent commit fixed the code that parses the firmware files before +downloading them to the controller but introduced a memory leak in case +the sanity checks ever fail. + +Make sure to free the firmware buffer before returning on errors. + +Fixes: f905ae0be4b7 ("Bluetooth: qca: add missing firmware sanity checks") +Cc: stable@vger.kernel.org # 4.19 +Signed-off-by: Johan Hovold +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/btqca.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/bluetooth/btqca.c ++++ b/drivers/bluetooth/btqca.c +@@ -492,7 +492,7 @@ static int qca_download_firmware(struct + + ret = qca_tlv_check_data(hdev, config, data, size, soc_type); + if (ret) +- return ret; ++ goto out; + + segment = data; + remain = size; diff --git a/queue-5.15/bluetooth-qca-fix-nvm-configuration-parsing.patch b/queue-5.15/bluetooth-qca-fix-nvm-configuration-parsing.patch new file mode 100644 index 00000000000..b3c3b045d7e --- /dev/null +++ b/queue-5.15/bluetooth-qca-fix-nvm-configuration-parsing.patch @@ -0,0 +1,91 @@ +From a112d3c72a227f2edbb6d8094472cc6e503e52af Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 30 Apr 2024 19:07:40 +0200 +Subject: Bluetooth: qca: fix NVM configuration parsing + +From: Johan Hovold + +commit a112d3c72a227f2edbb6d8094472cc6e503e52af upstream. + +The NVM configuration files used by WCN3988 and WCN3990/1/8 have two +sets of configuration tags that are enclosed by a type-length header of +type four which the current parser fails to account for. + +Instead the driver happily parses random data as if it were valid tags, +something which can lead to the configuration data being corrupted if it +ever encounters the words 0x0011 or 0x001b. + +As is clear from commit b63882549b2b ("Bluetooth: btqca: Fix the NVM +baudrate tag offcet for wcn3991") the intention has always been to +process the configuration data also for WCN3991 and WCN3998 which +encodes the baud rate at a different offset. + +Fix the parser so that it can handle the WCN3xxx configuration files, +which has an enclosing type-length header of type four and two sets of +TLV tags enclosed by a type-length header of type two and three, +respectively. + +Note that only the first set, which contains the tags the driver is +currently looking for, will be parsed for now. + +With the parser fixed, the software in-band sleep bit will now be set +for WCN3991 and WCN3998 (as it is for later controllers) and the default +baud rate 3200000 may be updated by the driver also for WCN3xxx +controllers. + +Notably the deep-sleep feature bit is already set by default in all +configuration files in linux-firmware. + +Fixes: 4219d4686875 ("Bluetooth: btqca: Add wcn3990 firmware download support.") +Cc: stable@vger.kernel.org # 4.19 +Cc: Matthias Kaehlcke +Signed-off-by: Johan Hovold +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/btqca.c | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +--- a/drivers/bluetooth/btqca.c ++++ b/drivers/bluetooth/btqca.c +@@ -195,6 +195,7 @@ static int qca_tlv_check_data(struct hci + struct tlv_type_patch *tlv_patch; + struct tlv_type_nvm *tlv_nvm; + uint8_t nvm_baud_rate = config->user_baud_rate; ++ u8 type; + + config->dnld_mode = QCA_SKIP_EVT_NONE; + config->dnld_type = QCA_SKIP_EVT_NONE; +@@ -260,11 +261,30 @@ static int qca_tlv_check_data(struct hci + tlv = (struct tlv_type_hdr *)fw_data; + + type_len = le32_to_cpu(tlv->type_len); +- length = (type_len >> 8) & 0x00ffffff; ++ length = type_len >> 8; ++ type = type_len & 0xff; + +- BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff); ++ /* Some NVM files have more than one set of tags, only parse ++ * the first set when it has type 2 for now. When there is ++ * more than one set there is an enclosing header of type 4. ++ */ ++ if (type == 4) { ++ if (fw_size < 2 * sizeof(struct tlv_type_hdr)) ++ return -EINVAL; ++ ++ tlv++; ++ ++ type_len = le32_to_cpu(tlv->type_len); ++ length = type_len >> 8; ++ type = type_len & 0xff; ++ } ++ ++ BT_DBG("TLV Type\t\t : 0x%x", type); + BT_DBG("Length\t\t : %d bytes", length); + ++ if (type != 2) ++ break; ++ + if (fw_size < length + (tlv->data - fw_data)) + return -EINVAL; + diff --git a/queue-5.15/series b/queue-5.15/series index 01c8403b90f..8089fc2bde9 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -169,3 +169,6 @@ drm-vmwgfx-fix-invalid-reads-in-fence-signaled-events.patch net-fix-out-of-bounds-access-in-ops_init.patch hwmon-pmbus-ucd9000-increase-delay-from-250-to-500us.patch regulator-core-fix-debugfs-creation-regression.patch +bluetooth-qca-add-missing-firmware-sanity-checks.patch +bluetooth-qca-fix-nvm-configuration-parsing.patch +bluetooth-qca-fix-firmware-check-error-path.patch -- 2.47.3