mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-12 17:34:30 -05:00
344 lines
11 KiB
Diff
344 lines
11 KiB
Diff
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
|
|
|