* [PATCH 0/3] Bluetooth: btintel_pcie: Fix array bounds of device-controlled indices
@ 2026-08-20 9:17 ZhaoJinming
2026-08-20 9:17 ` [PATCH 1/3] Bluetooth: btintel_pcie: Fix off-by-one bounds checks in synchronous paths ZhaoJinming
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: ZhaoJinming @ 2026-08-20 9:17 UTC (permalink / raw)
To: Luiz Augusto von Dentz, Marcel Holtmann, Paul Menzel
Cc: linux-bluetooth, linux-kernel
This series fixes four array bounds issues in the Intel BT PCIe driver
where device-controlled indices from shared DMA memory are used to
index fixed-size arrays without proper validation.
Link: https://lore.kernel.org/all/1217891c-bf57-4c1a-9963-27400f60a5cd@molgen.mpg.de/
Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
---
ZhaoJinming (3):
Bluetooth: btintel_pcie: Fix off-by-one bounds checks in synchronous paths
Bluetooth: btintel_pcie: Fix bounds checks in TX completion handler
Bluetooth: btintel_pcie: Fix bounds checks in RX completion handler
drivers/bluetooth/btintel_pcie.c | 78 ++++++++++++++++++++++++++++++++++------
1 file changed, 67 insertions(+), 11 deletions(-)
---
base-commit: a4ff2be345d0abc943da8dd8da98151843b750dc
change-id: 20260820-btintel_pcie_bounds_fixes-45a8aff3de36
Best regards,
--
ZhaoJinming <zhaojinming@uniontech.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/3] Bluetooth: btintel_pcie: Fix off-by-one bounds checks in synchronous paths
2026-08-20 9:17 [PATCH 0/3] Bluetooth: btintel_pcie: Fix array bounds of device-controlled indices ZhaoJinming
@ 2026-08-20 9:17 ` ZhaoJinming
2026-08-20 9:50 ` Bluetooth: btintel_pcie: Fix array bounds of device-controlled indices bluez.test.bot
2026-08-20 9:17 ` [PATCH 2/3] Bluetooth: btintel_pcie: Fix bounds checks in TX completion handler ZhaoJinming
2026-08-20 9:17 ` [PATCH 3/3] Bluetooth: btintel_pcie: Fix bounds checks in RX " ZhaoJinming
2 siblings, 1 reply; 5+ messages in thread
From: ZhaoJinming @ 2026-08-20 9:17 UTC (permalink / raw)
To: Luiz Augusto von Dentz, Marcel Holtmann, Paul Menzel
Cc: linux-bluetooth, linux-kernel
Fix two off-by-one errors where '>' should have been '>=' when
checking array indices against queue count:
1. btintel_pcie_send_sync(): tfd_index from tr_hia is used to index
txq->tfds[] and txq->bufs[]. When tfd_index == txq->count (32),
btintel_pcie_prepare_tx() writes past the end of both arrays.
2. btintel_pcie_submit_rx(): frbd_index from tr_hia is used to index
rxq->frbds[] and rxq->bufs[]. When frbd_index == rxq->count (64),
btintel_pcie_prepare_rx() writes past the end of both arrays.
Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
---
drivers/bluetooth/btintel_pcie.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index 2b7231be5973d399f7f2fde344032b2f3e394365..fe50c5699e12ef3819577e0f0bd1b79d4340bd9e 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -401,7 +401,7 @@ static int btintel_pcie_send_sync(struct btintel_pcie_data *data,
tfd_index = data->ia.tr_hia[BTINTEL_PCIE_TXQ_NUM];
- if (tfd_index > txq->count)
+ if (tfd_index >= txq->count)
return -ERANGE;
/* Firmware raises alive interrupt on HCI_OP_RESET or
@@ -502,7 +502,7 @@ static int btintel_pcie_submit_rx(struct btintel_pcie_data *data)
frbd_index = data->ia.tr_hia[BTINTEL_PCIE_RXQ_NUM];
- if (frbd_index > rxq->count)
+ if (frbd_index >= rxq->count)
return -ERANGE;
/* Prepare for RX submit. It updates the FRBD with the address of DMA
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] Bluetooth: btintel_pcie: Fix bounds checks in TX completion handler
2026-08-20 9:17 [PATCH 0/3] Bluetooth: btintel_pcie: Fix array bounds of device-controlled indices ZhaoJinming
2026-08-20 9:17 ` [PATCH 1/3] Bluetooth: btintel_pcie: Fix off-by-one bounds checks in synchronous paths ZhaoJinming
@ 2026-08-20 9:17 ` ZhaoJinming
2026-08-20 9:17 ` [PATCH 3/3] Bluetooth: btintel_pcie: Fix bounds checks in RX " ZhaoJinming
2 siblings, 0 replies; 5+ messages in thread
From: ZhaoJinming @ 2026-08-20 9:17 UTC (permalink / raw)
To: Luiz Augusto von Dentz, Marcel Holtmann, Paul Menzel
Cc: linux-bluetooth, linux-kernel
Fix two issues in btintel_pcie_msix_tx_handle():
1. cr_tia is a device-controlled value from shared DMA memory
(data->ia.cr_tia[]) and is used to index txq->urbd0s[] without
a bounds check. An out-of-range value could cause an out-of-bounds
access when indexing txq->urbd0s[]. Add a bounds check before the
array access. When cr_tia is out of range, reset the ring consumer
pointer (data->ia.cr_tia[]) to cr_hia so the queue can recover on
the next interrupt.
2. The existing check on urbd0->tfd_index uses '>' instead of '>=',
allowing tfd_index == txq->count (32) to pass. This check guards
against a device-controlled value, so the comparison must reject
all out-of-range indices. Read tfd_index via READ_ONCE() to
ensure a single atomic read from DMA-coherent memory.
Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
---
drivers/bluetooth/btintel_pcie.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index fe50c5699e12ef3819577e0f0bd1b79d4340bd9e..c1fd5feb9f81bbd70fabd12b12eb4a1708f6a91f 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -1081,9 +1081,10 @@ static void btintel_pcie_msix_gp0_handler(struct btintel_pcie_data *data)
*/
static void btintel_pcie_msix_tx_handle(struct btintel_pcie_data *data)
{
- u16 cr_tia, cr_hia;
+ u16 cr_tia, cr_hia, tfd_index;
struct txq *txq;
struct urbd0 *urbd0;
+ struct hci_dev *hdev = data->hdev;
cr_tia = data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM];
cr_hia = data->ia.cr_hia[BTINTEL_PCIE_TXQ_NUM];
@@ -1094,13 +1095,36 @@ static void btintel_pcie_msix_tx_handle(struct btintel_pcie_data *data)
txq = &data->txq;
while (cr_tia != cr_hia) {
+ if (cr_tia >= txq->count) {
+ bt_dev_err(hdev, "TXQ: invalid cr_tia %u >= %u, contact device vendor",
+ cr_tia, txq->count);
+ /* Reset consumer pointer so the ring can
+ * recover on the next interrupt.
+ */
+ data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM] = cr_hia;
+ break;
+ }
+
data->tx_wait_done = true;
wake_up(&data->tx_wait_q);
urbd0 = &txq->urbd0s[cr_tia];
- if (urbd0->tfd_index > txq->count)
- return;
+ /* tfd_index is a bitfield in DMA-coherent memory;
+ * read the full word once with READ_ONCE to avoid
+ * TOCTOU race with the device.
+ */
+ tfd_index = READ_ONCE(*(const u32 *)urbd0) & 0xffff;
+
+ if (tfd_index >= txq->count) {
+ bt_dev_err(hdev, "TXQ: invalid tfd_index %u >= %u, contact device vendor",
+ tfd_index, txq->count);
+ /* Device provided invalid data. Leave cr_tia
+ * unchanged so the error remains detectable
+ * via repeated log messages, aiding debug.
+ */
+ break;
+ }
cr_tia = (cr_tia + 1) % txq->count;
data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM] = cr_tia;
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] Bluetooth: btintel_pcie: Fix bounds checks in RX completion handler
2026-08-20 9:17 [PATCH 0/3] Bluetooth: btintel_pcie: Fix array bounds of device-controlled indices ZhaoJinming
2026-08-20 9:17 ` [PATCH 1/3] Bluetooth: btintel_pcie: Fix off-by-one bounds checks in synchronous paths ZhaoJinming
2026-08-20 9:17 ` [PATCH 2/3] Bluetooth: btintel_pcie: Fix bounds checks in TX completion handler ZhaoJinming
@ 2026-08-20 9:17 ` ZhaoJinming
2 siblings, 0 replies; 5+ messages in thread
From: ZhaoJinming @ 2026-08-20 9:17 UTC (permalink / raw)
To: Luiz Augusto von Dentz, Marcel Holtmann, Paul Menzel
Cc: linux-bluetooth, linux-kernel
Fix three issues in btintel_pcie_msix_rx_handle():
1. cr_tia is a device-controlled value from shared DMA memory
(data->ia.cr_tia[]) and is used to index rxq->urbd1s[] without
a bounds check. An out-of-range value could cause an out-of-bounds
access when indexing rxq->urbd1s[]. Add a bounds check before the
array access. When cr_tia is out of range, reset the ring consumer
pointer (data->ia.cr_tia[]) to cr_hia so the queue can recover on
the next interrupt.
2. urbd1->frbd_tag is a 16-bit device-controlled field (0-65535)
used directly as an index into rxq->bufs[] (64 elements). Add a
bounds check. Read the field via READ_ONCE() to avoid a
Time-of-Check to Time-of-Use (TOCTOU) race, since the field is
in DMA-coherent memory and the compiler may emit two separate
reads.
3. All error paths in the while loop use 'return', which exits the
handler without advancing cr_tia. This causes the RX completion
queue to stall, as the next interrupt would process the same
corrupted descriptor and exit again. Change to 'break' to exit
the loop without further processing.
Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
---
drivers/bluetooth/btintel_pcie.c | 44 ++++++++++++++++++++++++++++++++++------
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index c1fd5feb9f81bbd70fabd12b12eb4a1708f6a91f..1f5537df620972d937f65e754701f65566e4655a 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -1586,7 +1586,7 @@ static int btintel_pcie_submit_rx_work(struct btintel_pcie_data *data, u8 status
/* Handles the MSI-X interrupt for rx queue 1 which is for RX */
static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
{
- u16 cr_hia, cr_tia;
+ u16 cr_hia, cr_tia, frbd_tag;
struct rxq *rxq;
struct urbd1 *urbd1;
struct data_buf *buf;
@@ -1608,21 +1608,53 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
* process all received CDs in this interrupt.
*/
while (cr_tia != cr_hia) {
+ if (cr_tia >= rxq->count) {
+ bt_dev_err(hdev, "RXQ: invalid cr_tia %u >= %u, contact device vendor",
+ cr_tia, rxq->count);
+ /* Reset consumer pointer so the ring can
+ * recover on the next interrupt.
+ */
+ data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM] = cr_hia;
+ break;
+ }
+
urbd1 = &rxq->urbd1s[cr_tia];
ipc_print_urbd1(data->hdev, urbd1, cr_tia);
- buf = &rxq->bufs[urbd1->frbd_tag];
+ /* frbd_tag is a bitfield in DMA-coherent memory;
+ * read the full word once with READ_ONCE to avoid
+ * TOCTOU race with the device.
+ */
+ frbd_tag = READ_ONCE(*(const u32 *)urbd1) & 0xffff;
+
+ if (frbd_tag >= rxq->count) {
+ bt_dev_err(hdev, "RXQ: invalid frbd_tag %u >= %u, contact device vendor",
+ frbd_tag, rxq->count);
+ /* Device provided invalid data. Leave cr_tia
+ * unchanged so the error remains detectable
+ * via repeated log messages, aiding debug.
+ */
+ break;
+ }
+
+ buf = &rxq->bufs[frbd_tag];
if (!buf) {
- bt_dev_err(hdev, "RXQ: failed to get the DMA buffer for %d",
- urbd1->frbd_tag);
- return;
+ bt_dev_err(hdev, "RXQ: failed to get the DMA buffer for %u",
+ frbd_tag);
+ /* Unexpected NULL pointer; leave cr_tia
+ * unchanged to keep the error visible.
+ */
+ break;
}
ret = btintel_pcie_submit_rx_work(data, urbd1->status,
buf->data);
if (ret) {
bt_dev_err(hdev, "RXQ: failed to submit rx request");
- return;
+ /* Submission failed; leave cr_tia unchanged
+ * to keep the error detectable on retry.
+ */
+ break;
}
cr_tia = (cr_tia + 1) % rxq->count;
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* RE: Bluetooth: btintel_pcie: Fix array bounds of device-controlled indices
2026-08-20 9:17 ` [PATCH 1/3] Bluetooth: btintel_pcie: Fix off-by-one bounds checks in synchronous paths ZhaoJinming
@ 2026-08-20 9:50 ` bluez.test.bot
0 siblings, 0 replies; 5+ messages in thread
From: bluez.test.bot @ 2026-08-20 9:50 UTC (permalink / raw)
To: linux-bluetooth, zhaojinming
[-- Attachment #1: Type: text/plain, Size: 1181 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1148965
---Test result---
Test Summary:
CheckPatch PASS 2.08 seconds
VerifyFixes PASS 0.12 seconds
VerifySignedoff PASS 0.12 seconds
GitLint PASS 0.91 seconds
SubjectPrefix PASS 0.33 seconds
BuildKernel PASS 27.65 seconds
CheckAllWarning PASS 30.69 seconds
CheckSparse PASS 29.33 seconds
BuildKernel32 PASS 27.31 seconds
CheckKernelLLVM SKIP 0.00 seconds
TestRunnerSetup PASS 505.28 seconds
IncrementalBuild PASS 29.95 seconds
Details
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found
https://github.com/bluez/bluetooth-next/pull/623
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-20 9:50 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-20 9:17 [PATCH 0/3] Bluetooth: btintel_pcie: Fix array bounds of device-controlled indices ZhaoJinming
2026-08-20 9:17 ` [PATCH 1/3] Bluetooth: btintel_pcie: Fix off-by-one bounds checks in synchronous paths ZhaoJinming
2026-08-20 9:50 ` Bluetooth: btintel_pcie: Fix array bounds of device-controlled indices bluez.test.bot
2026-08-20 9:17 ` [PATCH 2/3] Bluetooth: btintel_pcie: Fix bounds checks in TX completion handler ZhaoJinming
2026-08-20 9:17 ` [PATCH 3/3] Bluetooth: btintel_pcie: Fix bounds checks in RX " ZhaoJinming
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox