From f92b7bca985205082c86140d0bd7c86c5be00efc Mon Sep 17 00:00:00 2001 From: Catherine L Date: Fri, 23 Oct 2026 11:30:26 +0530 Subject: [PATCH] Bluetooth: btintel: fix buffer over-read in fw payload The firmware decoder cast fw_ptr + frag_len to struct hci_command_hdr and read cmd->plen before confirming the header and payload still fit in the remaining firmware buffer. Add explicit bounds checks before each dereference: 1. Reject if the command header is not fully contained in remain. 2. Reject if the full command including payload exceeds remain. 3. Log the offending fragment length and remaining size before returning -EINVAL. Fixes: fbbe83c52bc0d ("Bluetooth: btintel: Create common function for firmware download") Signed-off-by: Catherine L Tested-by: Kiran K Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/btintel.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 0709fb3212f9..929018428c19 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -1201,7 +1201,29 @@ static int btintel_download_firmware_payload(struct hci_dev *hdev, err = -EINVAL; while (fw_ptr - fw->data < fw->size) { - struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len); + struct hci_command_hdr *cmd; + size_t remain = fw->size - (fw_ptr - fw->data); + + /* Ensure the header fits before dereferencing */ + if (frag_len + sizeof(*cmd) > remain) { + bt_dev_err(hdev, + "Firmware buffer overrun at header (frag_len %u, need %zu, remain %zu)", + frag_len, frag_len + sizeof(*cmd), remain); + err = -EINVAL; + goto done; + } + + cmd = (void *)(fw_ptr + frag_len); + + /* Ensure the full command (header + payload) fits before use */ + if (frag_len + sizeof(*cmd) + cmd->plen > remain) { + bt_dev_err(hdev, + "Firmware buffer overrun at payload (frag_len %u, plen %u, need %zu, remain %zu)", + frag_len, cmd->plen, + frag_len + sizeof(*cmd) + cmd->plen, remain); + err = -EINVAL; + goto done; + } frag_len += sizeof(*cmd) + cmd->plen;