struct hci_uart *hu = hci_get_drvdata(hdev);
struct aml_serdev *amldev = serdev_device_get_drvdata(hu->serdev);
const struct firmware *firmware = NULL;
- struct aml_fw_len *fw_len = NULL;
+ const struct aml_fw_len *fw_len = NULL;
u8 *iccm_start = NULL, *dccm_start = NULL;
u32 iccm_len, dccm_len;
u32 value = 0;
goto exit;
}
- fw_len = (struct aml_fw_len *)firmware->data;
+ if (firmware->size < sizeof(*fw_len)) {
+ bt_dev_err(hdev, "Firmware is too small for its header");
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ fw_len = (const struct aml_fw_len *)firmware->data;
+ if (fw_len->iccm_len < amldev->aml_dev_data->iccm_offset ||
+ fw_len->iccm_len > firmware->size - sizeof(*fw_len) ||
+ fw_len->dccm_len > firmware->size - sizeof(*fw_len) -
+ fw_len->iccm_len) {
+ bt_dev_err(hdev, "Invalid firmware segment lengths");
+ ret = -EINVAL;
+ goto exit;
+ }
/* Download ICCM */
iccm_start = (u8 *)(firmware->data) + sizeof(struct aml_fw_len)