DivestOS/Patches/Linux_CVEs/CVE-2014-9864/ANY/0.patch

344 lines
11 KiB
Diff
Raw Normal View History

From a1124defc680055e2f2a8c8e3da4a94ca2ec842e Mon Sep 17 00:00:00 2001
From: Mona Hossain <mhossain@codeaurora.org>
Date: Tue, 1 Oct 2013 13:41:09 -0700
Subject: qseecom: Add checks for API called in IOCTL
Validate the caller is the right type for the IOCTL being
issued and inputs are valid.
Change-Id: Iad71f0f5ed4d53c5d011bd55cdf74ec053d09af5
Signed-off-by: Mona Hossain <mhossain@codeaurora.org>
Signed-off-by: Hariprasad Dhalinarasimha <hnamgund@codeaurora.org>
---
drivers/misc/qseecom.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 159 insertions(+), 6 deletions(-)
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 7cc1c9f..51f0228 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -434,6 +434,12 @@ static int qseecom_set_client_mem_param(struct qseecom_dev_handle *data,
if (copy_from_user(&req, (void __user *)argp, sizeof(req)))
return -EFAULT;
+ if ((req.ifd_data_fd <= 0) || (req.virt_sb_base == 0) ||
+ (req.sb_len == 0)) {
+ pr_err("Inavlid input(s)ion_fd(%d), sb_len(%d), vaddr(0x%x)\n",
+ req.ifd_data_fd, req.sb_len, req.virt_sb_base);
+ return -EFAULT;
+ }
/* Get the handle of the shared fd */
data->client.ihandle = ion_import_dma_buf(qseecom.ion_clnt,
req.ifd_data_fd);
@@ -2680,6 +2686,12 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
switch (cmd) {
case QSEECOM_IOCTL_REGISTER_LISTENER_REQ: {
+ if (data->type != QSEECOM_GENERIC) {
+ pr_err("reg lstnr req: invalid handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
pr_debug("ioctl register_listener_req()\n");
atomic_inc(&data->ioctl_count);
data->type = QSEECOM_LISTENER_SERVICE;
@@ -2691,6 +2703,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ: {
+ if ((data->listener.id == 0) ||
+ (data->type != QSEECOM_LISTENER_SERVICE)) {
+ pr_err("unreg lstnr req: invalid handle (%d) lid(%d)\n",
+ data->type, data->listener.id);
+ ret = -EINVAL;
+ break;
+ }
pr_debug("ioctl unregister_listener_req()\n");
atomic_inc(&data->ioctl_count);
ret = qseecom_unregister_listener(data);
@@ -2701,6 +2720,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_SEND_CMD_REQ: {
+ if ((data->client.app_id == 0) ||
+ (data->type != QSEECOM_CLIENT_APP)) {
+ pr_err("send cmd req: invalid handle (%d) app_id(%d)\n",
+ data->type, data->client.app_id);
+ ret = -EINVAL;
+ break;
+ }
/* Only one client allowed here at a time */
mutex_lock(&app_access_lock);
atomic_inc(&data->ioctl_count);
@@ -2713,6 +2739,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_SEND_MODFD_CMD_REQ: {
+ if ((data->client.app_id == 0) ||
+ (data->type != QSEECOM_CLIENT_APP)) {
+ pr_err("send mdfd cmd: invalid handle (%d) appid(%d)\n",
+ data->type, data->client.app_id);
+ ret = -EINVAL;
+ break;
+ }
/* Only one client allowed here at a time */
mutex_lock(&app_access_lock);
atomic_inc(&data->ioctl_count);
@@ -2725,6 +2758,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_RECEIVE_REQ: {
+ if ((data->listener.id == 0) ||
+ (data->type != QSEECOM_LISTENER_SERVICE)) {
+ pr_err("receive req: invalid handle (%d), lid(%d)\n",
+ data->type, data->listener.id);
+ ret = -EINVAL;
+ break;
+ }
atomic_inc(&data->ioctl_count);
ret = qseecom_receive_req(data);
atomic_dec(&data->ioctl_count);
@@ -2734,6 +2774,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_SEND_RESP_REQ: {
+ if ((data->listener.id == 0) ||
+ (data->type != QSEECOM_LISTENER_SERVICE)) {
+ pr_err("send resp req: invalid handle (%d), lid(%d)\n",
+ data->type, data->listener.id);
+ ret = -EINVAL;
+ break;
+ }
atomic_inc(&data->ioctl_count);
ret = qseecom_send_resp();
atomic_dec(&data->ioctl_count);
@@ -2743,7 +2790,14 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_SET_MEM_PARAM_REQ: {
- data->type = QSEECOM_CLIENT_APP;
+ if ((data->type != QSEECOM_CLIENT_APP) &&
+ (data->type != QSEECOM_GENERIC) &&
+ (data->type != QSEECOM_SECURE_SERVICE)) {
+ pr_err("set mem param req: invalid handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
pr_debug("SET_MEM_PARAM: qseecom addr = 0x%x\n", (u32)data);
ret = qseecom_set_client_mem_param(data, argp);
if (ret)
@@ -2752,6 +2806,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_LOAD_APP_REQ: {
+ if ((data->type != QSEECOM_GENERIC) &&
+ (data->type != QSEECOM_CLIENT_APP)) {
+ pr_err("load app req: invalid handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
data->type = QSEECOM_CLIENT_APP;
pr_debug("LOAD_APP_REQ: qseecom_addr = 0x%x\n", (u32)data);
mutex_lock(&app_access_lock);
@@ -2772,6 +2833,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_UNLOAD_APP_REQ: {
+ if ((data->client.app_id == 0) ||
+ (data->type != QSEECOM_CLIENT_APP)) {
+ pr_err("unload app req:invalid handle(%d) app_id(%d)\n",
+ data->type, data->client.app_id);
+ ret = -EINVAL;
+ break;
+ }
pr_debug("UNLOAD_APP: qseecom_addr = 0x%x\n", (u32)data);
mutex_lock(&app_access_lock);
atomic_inc(&data->ioctl_count);
@@ -2791,6 +2859,20 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_PERF_ENABLE_REQ:{
+ if ((data->type != QSEECOM_GENERIC) &&
+ (data->type != QSEECOM_CLIENT_APP)) {
+ pr_err("perf enable req: invalid handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
+ if ((data->type == QSEECOM_CLIENT_APP) &&
+ (data->client.app_id == 0)) {
+ pr_err("perf enable req:invalid handle(%d) appid(%d)\n",
+ data->type, data->client.app_id);
+ ret = -EINVAL;
+ break;
+ }
atomic_inc(&data->ioctl_count);
ret = qsee_vote_for_clock(data, CLK_DFAB);
if (ret)
@@ -2802,13 +2884,33 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_PERF_DISABLE_REQ:{
+ if ((data->type != QSEECOM_SECURE_SERVICE) &&
+ (data->type != QSEECOM_CLIENT_APP)) {
+ pr_err("perf disable req: invalid handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
+ if ((data->type == QSEECOM_CLIENT_APP) &&
+ (data->client.app_id == 0)) {
+ pr_err("perf disable: invalid handle (%d)app_id(%d)\n",
+ data->type, data->client.app_id);
+ ret = -EINVAL;
+ break;
+ }
atomic_inc(&data->ioctl_count);
- qsee_disable_clock_vote(data, CLK_DFAB);
- qsee_disable_clock_vote(data, CLK_SFPB);
+ qsee_disable_clock_vote(data, CLK_DFAB);
+ qsee_disable_clock_vote(data, CLK_SFPB);
atomic_dec(&data->ioctl_count);
break;
}
case QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ: {
+ if (data->type != QSEECOM_GENERIC) {
+ pr_err("load ext elf req: invalid client handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
data->type = QSEECOM_UNAVAILABLE_CLIENT_APP;
data->released = true;
mutex_lock(&app_access_lock);
@@ -2821,6 +2923,12 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ: {
+ if (data->type != QSEECOM_UNAVAILABLE_CLIENT_APP) {
+ pr_err("unload ext elf req: invalid handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
data->released = true;
mutex_lock(&app_access_lock);
atomic_inc(&data->ioctl_count);
@@ -2842,9 +2950,15 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ: {
+ if (data->type != QSEECOM_GENERIC) {
+ pr_err("send cmd svc req: invalid handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
data->type = QSEECOM_SECURE_SERVICE;
if (qseecom.qsee_version < QSEE_VERSION_03) {
- pr_err("SEND_CMD_SERVICE_REQ: Invalid qsee version %u\n",
+ pr_err("SEND_CMD_SERVICE_REQ: Invalid qsee ver %u\n",
qseecom.qsee_version);
return -EINVAL;
}
@@ -2856,8 +2970,14 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_CREATE_KEY_REQ: {
+ if (data->type != QSEECOM_GENERIC) {
+ pr_err("create key req: invalid handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
if (qseecom.qsee_version < QSEE_VERSION_05) {
- pr_err("Create Key feature not supported in qsee version %u\n",
+ pr_err("Create Key feature unsupported: qsee ver %u\n",
qseecom.qsee_version);
return -EINVAL;
}
@@ -2873,8 +2993,14 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_WIPE_KEY_REQ: {
+ if (data->type != QSEECOM_GENERIC) {
+ pr_err("wipe key req: invalid handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
if (qseecom.qsee_version < QSEE_VERSION_05) {
- pr_err("Wipe Key feature not supported in qsee version %u\n",
+ pr_err("Wipe Key feature unsupported in qsee ver %u\n",
qseecom.qsee_version);
return -EINVAL;
}
@@ -2889,6 +3015,12 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_SAVE_PARTITION_HASH_REQ: {
+ if (data->type != QSEECOM_GENERIC) {
+ pr_err("save part hash req: invalid handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
data->released = true;
mutex_lock(&app_access_lock);
atomic_inc(&data->ioctl_count);
@@ -2898,6 +3030,12 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_IS_ES_ACTIVATED_REQ: {
+ if (data->type != QSEECOM_GENERIC) {
+ pr_err("ES activated req: invalid handle (%d)\n",
+ data->type);
+ ret = -EINVAL;
+ break;
+ }
data->released = true;
mutex_lock(&app_access_lock);
atomic_inc(&data->ioctl_count);
@@ -2907,6 +3045,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_SEND_MODFD_RESP: {
+ if ((data->listener.id == 0) ||
+ (data->type != QSEECOM_LISTENER_SERVICE)) {
+ pr_err("receive req: invalid handle (%d), lid(%d)\n",
+ data->type, data->listener.id);
+ ret = -EINVAL;
+ break;
+ }
/* Only one client allowed here at a time */
atomic_inc(&data->ioctl_count);
ret = qseecom_send_modfd_resp(data, argp);
@@ -2917,6 +3062,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
case QSEECOM_IOCTL_UNPROTECT_BUF: {
+ if ((data->listener.id == 0) ||
+ (data->type != QSEECOM_LISTENER_SERVICE)) {
+ pr_err("receive req: invalid handle (%d), lid(%d)\n",
+ data->type, data->listener.id);
+ ret = -EINVAL;
+ break;
+ }
/* Only one client allowed here at a time */
atomic_inc(&data->ioctl_count);
ret = qseecom_unprotect_buffer(argp);
@@ -2927,6 +3079,7 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
break;
}
default:
+ pr_err("Invalid IOCTL: %d\n", cmd);
return -EINVAL;
}
return ret;
--
cgit v1.1