diff options
author | Zhang Zhijie <zhangzj@rock-chips.com> | 2017-04-18 15:40:59 +0800 |
---|---|---|
committer | Huang, Tao <huangtao@rock-chips.com> | 2017-04-20 08:55:05 +0800 |
commit | 49b641fab164e22bbf1f4ef2cbcd46eee89aa68a (patch) | |
tree | 829b655bc3bab71fbd2bb508915dfaa9ae4a9ee5 /security/optee_linuxdriver | |
parent | 0d8cf581f9910d40ae5d883e884c4cb63191ccd5 (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.c | 18 |
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 */ |