Merge "qseecom: check buffer size when loading firmware images"
This commit is contained in:
commit
3885b8e79b
|
@ -3397,7 +3397,7 @@ static bool __qseecom_is_fw_image_valid(const struct firmware *fw_entry)
|
|||
return true;
|
||||
}
|
||||
|
||||
static int __qseecom_get_fw_size(char *appname, uint32_t *fw_size,
|
||||
static int __qseecom_get_fw_size(const char *appname, uint32_t *fw_size,
|
||||
uint32_t *app_arch)
|
||||
{
|
||||
int ret = -1;
|
||||
|
@ -3435,14 +3435,21 @@ static int __qseecom_get_fw_size(char *appname, uint32_t *fw_size,
|
|||
}
|
||||
pr_debug("QSEE %s app, arch %u\n", appname, *app_arch);
|
||||
release_firmware(fw_entry);
|
||||
fw_entry = NULL;
|
||||
for (i = 0; i < num_images; i++) {
|
||||
memset(fw_name, 0, sizeof(fw_name));
|
||||
snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d", appname, i);
|
||||
ret = request_firmware(&fw_entry, fw_name, qseecom.pdev);
|
||||
if (ret)
|
||||
goto err;
|
||||
if (*fw_size > U32_MAX - fw_entry->size) {
|
||||
pr_err("QSEE %s app file size overflow\n", appname);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
*fw_size += fw_entry->size;
|
||||
release_firmware(fw_entry);
|
||||
fw_entry = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -3453,8 +3460,9 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int __qseecom_get_fw_data(char *appname, u8 *img_data,
|
||||
struct qseecom_load_app_ireq *load_req)
|
||||
static int __qseecom_get_fw_data(const char *appname, u8 *img_data,
|
||||
uint32_t fw_size,
|
||||
struct qseecom_load_app_ireq *load_req)
|
||||
{
|
||||
int ret = -1;
|
||||
int i = 0, rc = 0;
|
||||
|
@ -3474,6 +3482,12 @@ static int __qseecom_get_fw_data(char *appname, u8 *img_data,
|
|||
}
|
||||
|
||||
load_req->img_len = fw_entry->size;
|
||||
if (load_req->img_len > fw_size) {
|
||||
pr_err("app %s size %zu is larger than buf size %u\n",
|
||||
appname, fw_entry->size, fw_size);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
memcpy(img_data_ptr, fw_entry->data, fw_entry->size);
|
||||
img_data_ptr = img_data_ptr + fw_entry->size;
|
||||
load_req->mdt_len = fw_entry->size; /*Get MDT LEN*/
|
||||
|
@ -3492,6 +3506,7 @@ static int __qseecom_get_fw_data(char *appname, u8 *img_data,
|
|||
goto err;
|
||||
}
|
||||
release_firmware(fw_entry);
|
||||
fw_entry = NULL;
|
||||
for (i = 0; i < num_images; i++) {
|
||||
snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d", appname, i);
|
||||
ret = request_firmware(&fw_entry, fw_name, qseecom.pdev);
|
||||
|
@ -3499,10 +3514,17 @@ static int __qseecom_get_fw_data(char *appname, u8 *img_data,
|
|||
pr_err("Failed to locate blob %s\n", fw_name);
|
||||
goto err;
|
||||
}
|
||||
if ((fw_entry->size > U32_MAX - load_req->img_len) ||
|
||||
(fw_entry->size + load_req->img_len > fw_size)) {
|
||||
pr_err("Invalid file size for %s\n", fw_name);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
memcpy(img_data_ptr, fw_entry->data, fw_entry->size);
|
||||
img_data_ptr = img_data_ptr + fw_entry->size;
|
||||
load_req->img_len += fw_entry->size;
|
||||
release_firmware(fw_entry);
|
||||
fw_entry = NULL;
|
||||
}
|
||||
return ret;
|
||||
err:
|
||||
|
@ -3607,7 +3629,7 @@ static int __qseecom_load_fw(struct qseecom_dev_handle *data, char *appname)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = __qseecom_get_fw_data(appname, img_data, &load_req);
|
||||
ret = __qseecom_get_fw_data(appname, img_data, fw_size, &load_req);
|
||||
if (ret) {
|
||||
ret = -EIO;
|
||||
goto exit_free_img_data;
|
||||
|
@ -3729,7 +3751,7 @@ static int qseecom_load_commonlib_image(struct qseecom_dev_handle *data,
|
|||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
ret = __qseecom_get_fw_data(cmnlib_name, img_data, &load_req);
|
||||
ret = __qseecom_get_fw_data(cmnlib_name, img_data, fw_size, &load_req);
|
||||
if (ret) {
|
||||
ret = -EIO;
|
||||
goto exit_free_img_data;
|
||||
|
|
Loading…
Reference in New Issue