Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf3d7f64 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "qseecom: check buffer size when loading firmware images"

parents ab0f80a0 fc2ae27e
Loading
Loading
Loading
Loading
+27 −5
Original line number Diff line number Diff line
@@ -3590,7 +3590,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;
@@ -3628,14 +3628,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;
@@ -3646,7 +3653,8 @@ err:
	return ret;
}

static int __qseecom_get_fw_data(char *appname, u8 *img_data,
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;
@@ -3667,6 +3675,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*/
@@ -3685,6 +3699,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);
@@ -3692,10 +3707,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:
@@ -3800,7 +3822,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;
@@ -3921,7 +3943,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;