summaryrefslogtreecommitdiff
path: root/security/optee_linuxdriver
diff options
context:
space:
mode:
authorZhang Zhijie <zhangzj@rock-chips.com>2017-04-18 15:40:59 +0800
committerHuang, Tao <huangtao@rock-chips.com>2017-04-20 08:55:05 +0800
commit49b641fab164e22bbf1f4ef2cbcd46eee89aa68a (patch)
tree829b655bc3bab71fbd2bb508915dfaa9ae4a9ee5 /security/optee_linuxdriver
parent0d8cf581f9910d40ae5d883e884c4cb63191ccd5 (diff)
OP-TEE: fix operate user pointer bug in optee driver
Fix operate user pointer bug which causes panic in kernel. Change-Id: I7fcf74fb68dd0959e5ba64635c614f954d065281 Signed-off-by: Zhang Zhijie <zhangzj@rock-chips.com>
Diffstat (limited to 'security/optee_linuxdriver')
-rw-r--r--security/optee_linuxdriver/core/tee_session.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/security/optee_linuxdriver/core/tee_session.c b/security/optee_linuxdriver/core/tee_session.c
index 987e7c954c84..a1b7a71539b4 100644
--- a/security/optee_linuxdriver/core/tee_session.c
+++ b/security/optee_linuxdriver/core/tee_session.c
@@ -676,6 +676,7 @@ static void _update_client_tee_cmd(struct tee_session *sess,
{
int idx;
struct tee_context *ctx;
+ TEEC_Operation op;
BUG_ON(!cmd_io);
BUG_ON(!cmd_io->op);
@@ -694,6 +695,9 @@ static void _update_client_tee_cmd(struct tee_session *sess,
TEEC_NONE, TEEC_NONE, TEEC_NONE))
return;
+ if (tee_context_copy_from_client(ctx, &op, cmd_io->op, sizeof(op)))
+ return;
+
for (idx = 0; idx < TEEC_CONFIG_PAYLOAD_REF_COUNT; ++idx) {
int type = TEEC_PARAM_TYPE_GET(cmd->param.type_original, idx);
int offset = 0;
@@ -728,11 +732,11 @@ static void _update_client_tee_cmd(struct tee_session *sess,
/* Returned updated size */
size_new = cmd->param.params[idx].shm->size_req;
if (size_new !=
- cmd_io->op->params[idx].tmpref.size) {
+ op.params[idx].tmpref.size) {
dev_dbg(_DEV_TEE,
"Size has been updated by the TA %zd != %zd\n",
size_new,
- cmd_io->op->params[idx].tmpref.size);
+ op.params[idx].tmpref.size);
tee_put_user(ctx, size_new,
&cmd_io->op->params[idx].tmpref.size);
}
@@ -741,15 +745,15 @@ static void _update_client_tee_cmd(struct tee_session *sess,
cmd->param.params[idx].shm->kaddr);
/* ensure we do not exceed the shared buffer length */
- if (size_new > cmd_io->op->params[idx].tmpref.size)
+ if (size_new > op.params[idx].tmpref.size)
dev_err(_DEV_TEE,
" *** Wrong returned size from %d:%zd > %zd\n",
idx, size_new,
- cmd_io->op->params[idx].tmpref.size);
+ op.params[idx].tmpref.size);
else if (tee_copy_to_user
(ctx,
- cmd_io->op->params[idx].tmpref.buffer,
+ op.params[idx].tmpref.buffer,
cmd->param.params[idx].shm->kaddr,
size_new))
dev_err(_DEV_TEE,
@@ -765,8 +769,8 @@ static void _update_client_tee_cmd(struct tee_session *sess,
offset = 0;
size = parent->size;
} else {
- offset = cmd_io->op->params[idx].memref.offset;
- size = cmd_io->op->params[idx].memref.size;
+ offset = op.params[idx].memref.offset;
+ size = op.params[idx].memref.size;
}
/* Returned updated size */