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>,
Paul Menzel <pmenzel@molgen.mpg.de>,
linux-bluetooth <linux-bluetooth@vger.kernel.org>,
linux-kernel <linux-kernel@vger.kernel.org>,
linux-mediatek <linux-mediatek@lists.infradead.org>,
Chris Lu <chris.lu@mediatek.com>
Subject: [PATCH v13 1/7] Bluetooth: btmtksdio: Fix SKB handling issues in TX path
Date: Thu, 16 Jul 2026 19:23:46 +0800 [thread overview]
Message-ID: <20260716112353.2192865-2-chris.lu@mediatek.com> (raw)
In-Reply-To: <20260716112353.2192865-1-chris.lu@mediatek.com>
Fix two SKB handling issues in btmtksdio_tx_packet():
1. DMA out-of-bounds read: The driver aligns transfer size to 256 bytes
using round_up(), but does not ensure the skb buffer has sufficient
tailroom, causing DMA to read beyond the buffer. Fix by expanding skb
tailroom if needed and zero-filling the padding.
2. Cloned SKB corruption: The driver modifies SKB header (via skb_push)
and tail (via skb_put_zero) without checking if the SKB is cloned.
If the Bluetooth core passes a cloned SKB (e.g., from L2CAP
retransmission queues), the driver corrupts the shared data buffer
for other subsystems. Fix by calling skb_unshare() at function entry
to ensure we have a private copy before any modifications.
Fixes: 9aebfd4a2200 ("Bluetooth: mediatek: add support for MediaTek MT7663S and MT7668S SDIO devices")
Signed-off-by: Chris Lu <chris.lu@mediatek.com>
Assisted-by: Claude:Sonnet-4.5
---
drivers/bluetooth/btmtksdio.c | 42 ++++++++++++++++++++++++++++++-----
1 file changed, 37 insertions(+), 5 deletions(-)
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index 5b0fab7b89b5..8a7f2e1c4d56 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -272,9 +272,20 @@ static int btmtksdio_tx_packet(struct btmtksdio_dev *bdev,
struct sk_buff *skb)
{
struct mtkbtsdio_hdr *sdio_hdr;
+ unsigned int padded_len, pad_len;
int err;
- /* Make sure that there are enough rooms for SDIO header */
+ /* Ensure SKB is not cloned before any modification.
+ * If cloned (e.g., L2CAP retransmission queues), create a
+ * private copy to avoid corrupting shared data buffer.
+ */
+ skb = skb_unshare(skb, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ /* Make sure that there are enough rooms for SDIO header.
+ * After skb_unshare(), we have exclusive ownership of the buffer.
+ */
if (unlikely(skb_headroom(skb) < sizeof(*sdio_hdr))) {
err = pskb_expand_head(skb, sizeof(*sdio_hdr), 0,
GFP_ATOMIC);
@@ -290,18 +301,39 @@ static int btmtksdio_tx_packet(struct btmtksdio_dev *bdev,
sdio_hdr->reserved = cpu_to_le16(0);
sdio_hdr->bt_type = hci_skb_pkt_type(skb);
+ /* Calculate padded length for block-aligned DMA transfer.
+ * SDIO requires transfers to be block-aligned (MTK_SDIO_BLOCK_SIZE).
+ * Pad with zeros to prevent DMA from reading beyond skb buffer.
+ */
+ padded_len = round_up(skb->len, MTK_SDIO_BLOCK_SIZE);
+ pad_len = padded_len - skb->len;
+
+ if (pad_len > 0) {
+ /* Ensure sufficient tailroom for padding */
+ if (unlikely(skb_tailroom(skb) < pad_len)) {
+ err = pskb_expand_head(skb, 0, pad_len, GFP_ATOMIC);
+ if (err < 0)
+ goto err_skb_pull;
+ /* Reassign sdio_hdr after buffer reallocation */
+ sdio_hdr = (void *)skb->data;
+ }
+
+ /* Zero-fill padding to prevent information disclosure */
+ skb_put_zero(skb, pad_len);
+ }
+
clear_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state);
- err = sdio_writesb(bdev->func, MTK_REG_CTDR, skb->data,
- round_up(skb->len, MTK_SDIO_BLOCK_SIZE));
+ err = sdio_writesb(bdev->func, MTK_REG_CTDR, skb->data, padded_len);
if (err < 0)
- goto err_skb_pull;
+ goto err_skb_trim;
- bdev->hdev->stat.byte_tx += skb->len;
+ /* Record actual transmitted data (excluding padding) */
+ bdev->hdev->stat.byte_tx += le16_to_cpu(sdio_hdr->len);
kfree_skb(skb);
return 0;
+err_skb_trim:
+ if (pad_len > 0)
+ skb_trim(skb, skb->len - pad_len);
err_skb_pull:
skb_pull(skb, sizeof(*sdio_hdr));
+ kfree_skb(skb);
return err;
}
--
2.45.2
next prev parent reply other threads:[~2026-07-16 11:25 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-16 11:23 [PATCH v13 0/7] Bluetooth: btmtk: Add MT7928 support Chris Lu
2026-07-16 11:23 ` Chris Lu [this message]
2026-07-16 12:02 ` bluez.test.bot
2026-07-16 11:23 ` [PATCH v13 2/7] Bluetooth: btmtk: Add firmware size validation in btmtk_setup_firmware_79xx() Chris Lu
2026-07-16 11:23 ` [PATCH v13 3/7] Bluetooth: btmtksdio: Pass hardware dev_id to mt79xx_setup() Chris Lu
2026-07-16 11:23 ` [PATCH v13 4/7] Bluetooth: btmtksdio: Remove redundant firmware filename override Chris Lu
2026-07-16 11:23 ` [PATCH v13 5/7] Bluetooth: btmtk: Improve BT firmware logging Chris Lu
2026-07-16 11:23 ` [PATCH v13 6/7] Bluetooth: btmtk: Replace magic numbers with WMT packet flag enum Chris Lu
2026-07-16 11:23 ` [PATCH v13 7/7] Bluetooth: btmtk: Add MT7928 support 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=20260716112353.2192865-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.