Skip to content
Permalink
Browse files

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>
  • Loading branch information...
jenswi-linaro authored and jforissier committed Nov 20, 2018
1 parent c6edc12 commit d5c5b0b77b2b589666024d219a8007b3f5b6faeb
Showing with 15 additions and 3 deletions.
  1. +15 −3 core/tee/tee_svc.c
@@ -494,7 +494,9 @@ TEE_Result syscall_get_property_name_to_index(unsigned long prop_set,
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)) {

0 comments on commit d5c5b0b

Please sign in to comment.
You can’t perform that action at this time.