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: fbbe83c52b ("Bluetooth: btintel: Create common function for firmware download")
Signed-off-by: Catherine L <catherine.l@intel.com>
Tested-by: Kiran K <kiran.k@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Catherine L 2026-10-23 11:30:26 +05:30 committed by Luiz Augusto von Dentz
parent 19b4e57017
commit f92b7bca98

View File

@ -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;