From: Chris Lu <chris.lu@mediatek.com>
To: Marcel Holtmann <marcel@holtmann.org>,
Johan Hedberg <johan.hedberg@gmail.com>,
Luiz Von Dentz <luiz.dentz@gmail.com>
Cc: Sean Wang <sean.wang@mediatek.com>,
Will Lee <will-cy.Lee@mediatek.com>, SS Wu <ss.wu@mediatek.com>,
Steve Lee <steve.lee@mediatek.com>,
linux-bluetooth <linux-bluetooth@vger.kernel.org>,
linux-kernel <linux-kernel@vger.kernel.org>,
linux-mediatek <linux-mediatek@lists.infradead.org>,
Paul Menzel <pmenzel@molgen.mpg.de>,
Chris Lu <chris.lu@mediatek.com>
Subject: [PATCH v9 1/6] Bluetooth: btmtk: Add firmware size validation in btmtk_setup_firmware_79xx()
Date: Thu, 2 Jul 2026 18:14:31 +0800 [thread overview]
Message-ID: <20260702101437.1787800-2-chris.lu@mediatek.com> (raw)
In-Reply-To: <20260702101437.1787800-1-chris.lu@mediatek.com>
Add firmware size validation to prevent out-of-bounds access when loading
truncated or malicious firmware files.
Add three levels of validation:
1. Minimum size check for header and global descriptor
2. Section map bounds check with integer overflow protection using
check_mul_overflow() and check_add_overflow()
3. Section data bounds check before accessing each section
This matches the validation approach used in btmtk_load_cbmcu_firmware().
Signed-off-by: Chris Lu <chris.lu@mediatek.com>
Assisted-by: Claude:Sonnet-4.5
---
drivers/bluetooth/btmtk.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 02a96342e964..3491060b3ae9 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -145,6 +145,7 @@ int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
int err, dlen, i, status;
u8 flag, first_block, retry;
u32 section_num, dl_size, section_offset;
+ size_t expected_size;
u8 cmd[64];
err = request_firmware(&fw, fwname, &hdev->dev);
@@ -153,12 +154,40 @@ int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
return err;
}
+ /* Validate minimum firmware size for header and global descriptor */
+ if (fw->size < MTK_FW_ROM_PATCH_HEADER_SIZE + MTK_FW_ROM_PATCH_GD_SIZE) {
+ bt_dev_err(hdev, "Firmware file too small: size=%zu, expected at least %u bytes",
+ fw->size, MTK_FW_ROM_PATCH_HEADER_SIZE + MTK_FW_ROM_PATCH_GD_SIZE);
+ err = -EINVAL;
+ goto err_release_fw;
+ }
+
fw_ptr = fw->data;
fw_bin_ptr = fw_ptr;
hdr = (struct btmtk_patch_header *)fw_ptr;
globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE);
section_num = le32_to_cpu(globaldesc->section_num);
+ /* Check for potential integer overflow in size calculation */
+ if (check_mul_overflow((size_t)MTK_FW_ROM_PATCH_SEC_MAP_SIZE,
+ (size_t)section_num, &expected_size) ||
+ check_add_overflow(expected_size,
+ (size_t)(MTK_FW_ROM_PATCH_HEADER_SIZE +
+ MTK_FW_ROM_PATCH_GD_SIZE),
+ &expected_size)) {
+ bt_dev_err(hdev, "Firmware size calculation overflow (section_num=%u)",
+ section_num);
+ err = -EINVAL;
+ goto err_release_fw;
+ }
+
+ if (fw->size < expected_size) {
+ bt_dev_err(hdev, "Firmware truncated: size=%zu, expected=%zu (section_num=%u)",
+ fw->size, expected_size, section_num);
+ err = -EINVAL;
+ goto err_release_fw;
+ }
+
bt_dev_info(hdev, "HW/SW Version: 0x%04x%04x, Build Time: %s",
le16_to_cpu(hdr->hwver), le16_to_cpu(hdr->swver), hdr->datetime);
@@ -171,6 +200,16 @@ int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
section_offset = le32_to_cpu(sectionmap->secoffset);
dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize);
+ /* Validate section boundaries to prevent out-of-bounds access */
+ if (dl_size > 0 &&
+ (section_offset > fw->size ||
+ dl_size > fw->size - section_offset)) {
+ bt_dev_err(hdev, "Section %d out of bounds: offset=%u, size=%u, fw_size=%zu",
+ i, section_offset, dl_size, fw->size);
+ err = -EINVAL;
+ goto err_release_fw;
+ }
+
/* MT6639: only download sections where dlmode byte0 == 0x01,
* matching the Windows driver behavior which skips WiFi/other
* sections that would cause the chip to hang.
--
2.45.2
next prev parent reply other threads:[~2026-07-02 10:14 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-02 10:14 [PATCH v9 0/6] Bluetooth: btmtk: Add MT7928 support Chris Lu
2026-07-02 10:14 ` Chris Lu [this message]
2026-07-02 10:51 ` bluez.test.bot
2026-07-02 10:14 ` [PATCH v9 2/6] Bluetooth: btmtksdio: Remove redundant firmware filename override Chris Lu
2026-07-02 10:14 ` [PATCH v9 3/6] Bluetooth: btmtksdio: Pass hardware dev_id to mt79xx_setup() Chris Lu
2026-07-02 10:14 ` [PATCH v9 4/6] Bluetooth: btmtk: Replace magic numbers with WMT packet flag enum Chris Lu
2026-07-02 10:14 ` [PATCH v9 5/6] Bluetooth: btmtk: Improve BT firmware logging Chris Lu
2026-07-02 10:14 ` [PATCH v9 6/6] Bluetooth: btmtk: Add MT7928 support Chris Lu
2026-07-04 3:37 ` [PATCH v9 0/6] " Chris Lu (陸稚泓)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260702101437.1787800-2-chris.lu@mediatek.com \
--to=chris.lu@mediatek.com \
--cc=johan.hedberg@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=luiz.dentz@gmail.com \
--cc=marcel@holtmann.org \
--cc=pmenzel@molgen.mpg.de \
--cc=sean.wang@mediatek.com \
--cc=ss.wu@mediatek.com \
--cc=steve.lee@mediatek.com \
--cc=will-cy.Lee@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.