From e65a876a155de945e306f2726f3a557415e6044e Mon Sep 17 00:00:00 2001 From: Mona Hossain Date: Tue, 1 Oct 2013 14:08:20 -0700 Subject: qseecom: Validate inputs from user space Validate send_cmd, send_modfd_cmd and send_mdfd_resp input parameters: cmd and response pointers and buffer lengths and offsets issued to modify data. Change-Id: I381836d08aaa48357486fbdc6a122eb5b42bfa0b Signed-off-by: Mona Hossain --- drivers/misc/qseecom.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 4c1943b..97f3362 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -1134,9 +1134,22 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data, pr_err("cmd buffer or response buffer is null\n"); return -EINVAL; } + if (((uint32_t)req->cmd_req_buf < data->client.user_virt_sb_base) || + ((uint32_t)req->cmd_req_buf >= (data->client.user_virt_sb_base + + data->client.sb_length))) { + pr_err("cmd buffer address not within shared bufffer\n"); + return -EINVAL; + } + + + if (((uint32_t)req->resp_buf < data->client.user_virt_sb_base) || + ((uint32_t)req->resp_buf >= (data->client.user_virt_sb_base + + data->client.sb_length))){ + pr_err("response buffer address not within shared bufffer\n"); + return -EINVAL; + } - if (req->cmd_req_len <= 0 || - req->resp_len <= 0 || + if ((req->cmd_req_len == 0) || (req->resp_len == 0) || req->cmd_req_len > data->client.sb_length || req->resp_len > data->client.sb_length) { pr_err("cmd buffer length or " @@ -1371,6 +1384,7 @@ static int qseecom_send_modfd_cmd(struct qseecom_dev_handle *data, void __user *argp) { int ret = 0; + int i; struct qseecom_send_modfd_cmd_req req; struct qseecom_send_cmd_req send_cmd_req; @@ -1384,6 +1398,14 @@ static int qseecom_send_modfd_cmd(struct qseecom_dev_handle *data, send_cmd_req.resp_buf = req.resp_buf; send_cmd_req.resp_len = req.resp_len; + /* validate offsets */ + for (i = 0; i < MAX_ION_FD; i++) { + if (req.ifd_data[i].cmd_buf_offset >= req.cmd_req_len) { + pr_err("Invalid offset %d = 0x%x\n", + i, req.ifd_data[i].cmd_buf_offset); + return -EINVAL; + } + } ret = __qseecom_update_cmd_buf(&req, false, data, false); if (ret) return ret; @@ -2001,11 +2023,20 @@ static int qseecom_send_modfd_resp(struct qseecom_dev_handle *data, void __user *argp) { struct qseecom_send_modfd_listener_resp resp; + int i; if (copy_from_user(&resp, argp, sizeof(resp))) { pr_err("copy_from_user failed"); return -EINVAL; } + /* validate offsets */ + for (i = 0; i < MAX_ION_FD; i++) { + if (resp.ifd_data[i].cmd_buf_offset >= resp.resp_len) { + pr_err("Invalid offset %d = 0x%x\n", + i, resp.ifd_data[i].cmd_buf_offset); + return -EINVAL; + } + } __qseecom_update_cmd_buf(&resp, false, data, true); qseecom.send_resp_flag = 1; wake_up_interruptible(&qseecom.send_resp_wq); -- cgit v1.1