aboutsummaryrefslogtreecommitdiff
path: root/core/tee
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2018-11-20 09:56:58 +0100
committerJérôme Forissier <jerome.forissier@linaro.org>2019-01-21 18:28:37 +0100
commitd5c5b0b77b2b589666024d219a8007b3f5b6faeb (patch)
treed006445eba5d16fbc467455fa57de64edd050a36 /core/tee
parentc6edc12acd490e272aade091b5f2389eba37bb33 (diff)
core: svc: always check ta parameters
Always check TA parameters from a user TA. This prevents a user TA from passing invalid pointers to a pseudo TA. Fixes: OP-TEE-2018-0007: "Buffer checks missing when calling pseudo TAs". Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Tested-by: Joakim Bech <joakim.bech@linaro.org> (QEMU v7, v8) Reviewed-by: Joakim Bech <joakim.bech@linaro.org> Reported-by: Riscure <inforequest@riscure.com> Reported-by: Alyssa Milburn <a.a.milburn@vu.nl> Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
Diffstat (limited to 'core/tee')
-rw-r--r--core/tee/tee_svc.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/core/tee/tee_svc.c b/core/tee/tee_svc.c
index 01392ba2..2be5b3f5 100644
--- a/core/tee/tee_svc.c
+++ b/core/tee/tee_svc.c
@@ -494,7 +494,9 @@ out:
return res;
}
-static void utee_param_to_param(struct tee_ta_param *p, struct utee_params *up)
+static TEE_Result utee_param_to_param(struct user_ta_ctx *utc,
+ struct tee_ta_param *p,
+ struct utee_params *up)
{
size_t n;
uint32_t types = up->types;
@@ -503,14 +505,20 @@ static void utee_param_to_param(struct tee_ta_param *p, struct utee_params *up)
for (n = 0; n < TEE_NUM_PARAMS; n++) {
uintptr_t a = up->vals[n * 2];
size_t b = up->vals[n * 2 + 1];
+ uint32_t flags = TEE_MEMORY_ACCESS_READ |
+ TEE_MEMORY_ACCESS_ANY_OWNER;
switch (TEE_PARAM_TYPE_GET(types, n)) {
- case TEE_PARAM_TYPE_MEMREF_INPUT:
case TEE_PARAM_TYPE_MEMREF_OUTPUT:
case TEE_PARAM_TYPE_MEMREF_INOUT:
+ flags |= TEE_MEMORY_ACCESS_WRITE;
+ /*FALLTHROUGH*/
+ case TEE_PARAM_TYPE_MEMREF_INPUT:
p->u[n].mem.mobj = &mobj_virt;
p->u[n].mem.offs = a;
p->u[n].mem.size = b;
+ if (tee_mmu_check_access_rights(utc, flags, a, b))
+ return TEE_ERROR_ACCESS_DENIED;
break;
case TEE_PARAM_TYPE_VALUE_INPUT:
case TEE_PARAM_TYPE_VALUE_INOUT:
@@ -522,6 +530,8 @@ static void utee_param_to_param(struct tee_ta_param *p, struct utee_params *up)
break;
}
}
+
+ return TEE_SUCCESS;
}
static TEE_Result alloc_temp_sec_mem(size_t size, struct mobj **mobj,
@@ -575,7 +585,9 @@ static TEE_Result tee_svc_copy_param(struct tee_ta_session *sess,
(uaddr_t)callee_params, sizeof(struct utee_params));
if (res != TEE_SUCCESS)
return res;
- utee_param_to_param(param, callee_params);
+ res = utee_param_to_param(utc, param, callee_params);
+ if (res != TEE_SUCCESS)
+ return res;
}
if (called_sess && is_pseudo_ta_ctx(called_sess->ctx)) {