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;