mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-25 15:39:26 -05:00
123 lines
3.9 KiB
Diff
123 lines
3.9 KiB
Diff
|
From fc2ae27eb9721a0ce050c2062734fec545cda604 Mon Sep 17 00:00:00 2001
|
||
|
From: Zhen Kong <zkong@codeaurora.org>
|
||
|
Date: Thu, 20 Oct 2016 17:34:20 -0700
|
||
|
Subject: qseecom: check buffer size when loading firmware images
|
||
|
|
||
|
Make change in __qseecom_load_fw() and qseecom_load_commonlib_image()
|
||
|
to check buffer size before copying img to buffer.
|
||
|
|
||
|
CRs-fixed: 1080290
|
||
|
Change-Id: I0f48666ac948a9571e249598ae7cc19df9036b1d
|
||
|
Signed-off-by: Zhen Kong <zkong@codeaurora.org>
|
||
|
---
|
||
|
drivers/misc/qseecom.c | 32 +++++++++++++++++++++++++++-----
|
||
|
1 file changed, 27 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
|
||
|
index 061bc99..dc20841 100644
|
||
|
--- a/drivers/misc/qseecom.c
|
||
|
+++ b/drivers/misc/qseecom.c
|
||
|
@@ -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,8 +3653,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;
|
||
|
@@ -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;
|
||
|
--
|
||
|
cgit v1.1
|
||
|
|