Loading drivers/misc/qseecom.c +87 −63 Original line number Diff line number Diff line Loading @@ -2622,11 +2622,6 @@ int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr, return -EINVAL; } if ((!req_ptr->cmd_req_buf) || (!req_ptr->resp_buf)) { pr_err("Invalid req/resp buffer, exiting\n"); return -EINVAL; } /* Clients need to ensure req_buf is at base offset of shared buffer */ if ((uintptr_t)req_ptr->cmd_req_buf != data_ptr->client.user_virt_sb_base) { Loading @@ -2634,15 +2629,11 @@ int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr, return -EINVAL; } if (((uintptr_t)req_ptr->resp_buf < data_ptr->client.user_virt_sb_base) || ((uintptr_t)req_ptr->resp_buf >= (data_ptr->client.user_virt_sb_base + data_ptr->client.sb_length))){ pr_err("response buffer address not within shared bufffer\n"); if (data_ptr->client.sb_length < sizeof(struct qseecom_rpmb_provision_key)) { pr_err("shared buffer is too small to hold key type\n"); return -EINVAL; } req_buf = data_ptr->client.sb_virt; send_svc_ireq_ptr->qsee_cmd_id = req_ptr->cmd_id; Loading @@ -2669,36 +2660,6 @@ int __qseecom_process_fsm_key_svc_cmd(struct qseecom_dev_handle *data_ptr, return -EINVAL; } if (((uintptr_t)req_ptr->cmd_req_buf < data_ptr->client.user_virt_sb_base) || ((uintptr_t)req_ptr->cmd_req_buf >= (data_ptr->client.user_virt_sb_base + data_ptr->client.sb_length))) { pr_err("cmd buffer address not within shared bufffer\n"); return -EINVAL; } if (((uintptr_t)req_ptr->resp_buf < data_ptr->client.user_virt_sb_base) || ((uintptr_t)req_ptr->resp_buf >= (data_ptr->client.user_virt_sb_base + data_ptr->client.sb_length))){ pr_err("response buffer address not within shared bufffer\n"); return -EINVAL; } if ((req_ptr->cmd_req_len == 0) || (req_ptr->resp_len == 0) || req_ptr->cmd_req_len > data_ptr->client.sb_length || req_ptr->resp_len > data_ptr->client.sb_length) { pr_err("cmd buffer length or response buffer length not valid\n"); return -EINVAL; } if (req_ptr->cmd_req_len > UINT_MAX - req_ptr->resp_len) { pr_err("Integer overflow detected in req_len & rsp_len, exiting now\n"); return -EINVAL; } reqd_len_sb_in = req_ptr->cmd_req_len + req_ptr->resp_len; if (reqd_len_sb_in > data_ptr->client.sb_length) { pr_err("Not enough memory to fit cmd_buf and resp_buf. "); Loading @@ -2720,28 +2681,11 @@ int __qseecom_process_fsm_key_svc_cmd(struct qseecom_dev_handle *data_ptr, return ret; } static int qseecom_send_service_cmd(struct qseecom_dev_handle *data, void __user *argp) static int __validate_send_service_cmd_inputs(struct qseecom_dev_handle *data, struct qseecom_send_svc_cmd_req *req) { int ret = 0; struct qseecom_client_send_service_ireq send_svc_ireq; struct qseecom_client_send_fsm_key_req send_fsm_key_svc_ireq; struct qseecom_command_scm_resp resp; struct qseecom_send_svc_cmd_req req; void *send_req_ptr; size_t req_buf_size; /*struct qseecom_command_scm_resp resp;*/ if (copy_from_user(&req, (void __user *)argp, sizeof(req))) { pr_err("copy_from_user failed\n"); return -EFAULT; } if ((req.resp_buf == NULL) || (req.cmd_req_buf == NULL)) { pr_err("cmd buffer or response buffer is null\n"); if (!req || !req->resp_buf || !req->cmd_req_buf) { pr_err("req or cmd buffer or response buffer is null\n"); return -EINVAL; } Loading @@ -2765,6 +2709,86 @@ static int qseecom_send_service_cmd(struct qseecom_dev_handle *data, return -EINVAL; } if (((uintptr_t)req->cmd_req_buf < data->client.user_virt_sb_base) || ((uintptr_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 (((uintptr_t)req->resp_buf < data->client.user_virt_sb_base) || ((uintptr_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) || (req->cmd_req_len > data->client.sb_length) || (req->resp_len > data->client.sb_length)) { pr_err("cmd buf length or response buf length not valid\n"); return -EINVAL; } if (req->cmd_req_len > UINT_MAX - req->resp_len) { pr_err("Integer overflow detected in req_len & rsp_len\n"); return -EINVAL; } if ((req->cmd_req_len + req->resp_len) > data->client.sb_length) { pr_debug("Not enough memory to fit cmd_buf.\n"); pr_debug("resp_buf. Required: %u, Available: %zu\n", (req->cmd_req_len + req->resp_len), data->client.sb_length); return -ENOMEM; } if ((uintptr_t)req->cmd_req_buf > (ULONG_MAX - req->cmd_req_len)) { pr_err("Integer overflow in req_len & cmd_req_buf\n"); return -EINVAL; } if ((uintptr_t)req->resp_buf > (ULONG_MAX - req->resp_len)) { pr_err("Integer overflow in resp_len & resp_buf\n"); return -EINVAL; } if (data->client.user_virt_sb_base > (ULONG_MAX - data->client.sb_length)) { pr_err("Integer overflow in user_virt_sb_base & sb_length\n"); return -EINVAL; } if ((((uintptr_t)req->cmd_req_buf + req->cmd_req_len) > ((uintptr_t)data->client.user_virt_sb_base + data->client.sb_length)) || (((uintptr_t)req->resp_buf + req->resp_len) > ((uintptr_t)data->client.user_virt_sb_base + data->client.sb_length))) { pr_err("cmd buf or resp buf is out of shared buffer region\n"); return -EINVAL; } return 0; } static int qseecom_send_service_cmd(struct qseecom_dev_handle *data, void __user *argp) { int ret = 0; struct qseecom_client_send_service_ireq send_svc_ireq; struct qseecom_client_send_fsm_key_req send_fsm_key_svc_ireq; struct qseecom_command_scm_resp resp; struct qseecom_send_svc_cmd_req req; void *send_req_ptr; size_t req_buf_size; /*struct qseecom_command_scm_resp resp;*/ if (copy_from_user(&req, (void __user *)argp, sizeof(req))) { pr_err("copy_from_user failed\n"); return -EFAULT; } if (__validate_send_service_cmd_inputs(data, &req)) return -EINVAL; data->type = QSEECOM_SECURE_SERVICE; switch (req.cmd_id) { Loading Loading
drivers/misc/qseecom.c +87 −63 Original line number Diff line number Diff line Loading @@ -2622,11 +2622,6 @@ int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr, return -EINVAL; } if ((!req_ptr->cmd_req_buf) || (!req_ptr->resp_buf)) { pr_err("Invalid req/resp buffer, exiting\n"); return -EINVAL; } /* Clients need to ensure req_buf is at base offset of shared buffer */ if ((uintptr_t)req_ptr->cmd_req_buf != data_ptr->client.user_virt_sb_base) { Loading @@ -2634,15 +2629,11 @@ int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr, return -EINVAL; } if (((uintptr_t)req_ptr->resp_buf < data_ptr->client.user_virt_sb_base) || ((uintptr_t)req_ptr->resp_buf >= (data_ptr->client.user_virt_sb_base + data_ptr->client.sb_length))){ pr_err("response buffer address not within shared bufffer\n"); if (data_ptr->client.sb_length < sizeof(struct qseecom_rpmb_provision_key)) { pr_err("shared buffer is too small to hold key type\n"); return -EINVAL; } req_buf = data_ptr->client.sb_virt; send_svc_ireq_ptr->qsee_cmd_id = req_ptr->cmd_id; Loading @@ -2669,36 +2660,6 @@ int __qseecom_process_fsm_key_svc_cmd(struct qseecom_dev_handle *data_ptr, return -EINVAL; } if (((uintptr_t)req_ptr->cmd_req_buf < data_ptr->client.user_virt_sb_base) || ((uintptr_t)req_ptr->cmd_req_buf >= (data_ptr->client.user_virt_sb_base + data_ptr->client.sb_length))) { pr_err("cmd buffer address not within shared bufffer\n"); return -EINVAL; } if (((uintptr_t)req_ptr->resp_buf < data_ptr->client.user_virt_sb_base) || ((uintptr_t)req_ptr->resp_buf >= (data_ptr->client.user_virt_sb_base + data_ptr->client.sb_length))){ pr_err("response buffer address not within shared bufffer\n"); return -EINVAL; } if ((req_ptr->cmd_req_len == 0) || (req_ptr->resp_len == 0) || req_ptr->cmd_req_len > data_ptr->client.sb_length || req_ptr->resp_len > data_ptr->client.sb_length) { pr_err("cmd buffer length or response buffer length not valid\n"); return -EINVAL; } if (req_ptr->cmd_req_len > UINT_MAX - req_ptr->resp_len) { pr_err("Integer overflow detected in req_len & rsp_len, exiting now\n"); return -EINVAL; } reqd_len_sb_in = req_ptr->cmd_req_len + req_ptr->resp_len; if (reqd_len_sb_in > data_ptr->client.sb_length) { pr_err("Not enough memory to fit cmd_buf and resp_buf. "); Loading @@ -2720,28 +2681,11 @@ int __qseecom_process_fsm_key_svc_cmd(struct qseecom_dev_handle *data_ptr, return ret; } static int qseecom_send_service_cmd(struct qseecom_dev_handle *data, void __user *argp) static int __validate_send_service_cmd_inputs(struct qseecom_dev_handle *data, struct qseecom_send_svc_cmd_req *req) { int ret = 0; struct qseecom_client_send_service_ireq send_svc_ireq; struct qseecom_client_send_fsm_key_req send_fsm_key_svc_ireq; struct qseecom_command_scm_resp resp; struct qseecom_send_svc_cmd_req req; void *send_req_ptr; size_t req_buf_size; /*struct qseecom_command_scm_resp resp;*/ if (copy_from_user(&req, (void __user *)argp, sizeof(req))) { pr_err("copy_from_user failed\n"); return -EFAULT; } if ((req.resp_buf == NULL) || (req.cmd_req_buf == NULL)) { pr_err("cmd buffer or response buffer is null\n"); if (!req || !req->resp_buf || !req->cmd_req_buf) { pr_err("req or cmd buffer or response buffer is null\n"); return -EINVAL; } Loading @@ -2765,6 +2709,86 @@ static int qseecom_send_service_cmd(struct qseecom_dev_handle *data, return -EINVAL; } if (((uintptr_t)req->cmd_req_buf < data->client.user_virt_sb_base) || ((uintptr_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 (((uintptr_t)req->resp_buf < data->client.user_virt_sb_base) || ((uintptr_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) || (req->cmd_req_len > data->client.sb_length) || (req->resp_len > data->client.sb_length)) { pr_err("cmd buf length or response buf length not valid\n"); return -EINVAL; } if (req->cmd_req_len > UINT_MAX - req->resp_len) { pr_err("Integer overflow detected in req_len & rsp_len\n"); return -EINVAL; } if ((req->cmd_req_len + req->resp_len) > data->client.sb_length) { pr_debug("Not enough memory to fit cmd_buf.\n"); pr_debug("resp_buf. Required: %u, Available: %zu\n", (req->cmd_req_len + req->resp_len), data->client.sb_length); return -ENOMEM; } if ((uintptr_t)req->cmd_req_buf > (ULONG_MAX - req->cmd_req_len)) { pr_err("Integer overflow in req_len & cmd_req_buf\n"); return -EINVAL; } if ((uintptr_t)req->resp_buf > (ULONG_MAX - req->resp_len)) { pr_err("Integer overflow in resp_len & resp_buf\n"); return -EINVAL; } if (data->client.user_virt_sb_base > (ULONG_MAX - data->client.sb_length)) { pr_err("Integer overflow in user_virt_sb_base & sb_length\n"); return -EINVAL; } if ((((uintptr_t)req->cmd_req_buf + req->cmd_req_len) > ((uintptr_t)data->client.user_virt_sb_base + data->client.sb_length)) || (((uintptr_t)req->resp_buf + req->resp_len) > ((uintptr_t)data->client.user_virt_sb_base + data->client.sb_length))) { pr_err("cmd buf or resp buf is out of shared buffer region\n"); return -EINVAL; } return 0; } static int qseecom_send_service_cmd(struct qseecom_dev_handle *data, void __user *argp) { int ret = 0; struct qseecom_client_send_service_ireq send_svc_ireq; struct qseecom_client_send_fsm_key_req send_fsm_key_svc_ireq; struct qseecom_command_scm_resp resp; struct qseecom_send_svc_cmd_req req; void *send_req_ptr; size_t req_buf_size; /*struct qseecom_command_scm_resp resp;*/ if (copy_from_user(&req, (void __user *)argp, sizeof(req))) { pr_err("copy_from_user failed\n"); return -EFAULT; } if (__validate_send_service_cmd_inputs(data, &req)) return -EINVAL; data->type = QSEECOM_SECURE_SERVICE; switch (req.cmd_id) { Loading