diff options
author | Jens Wiklander <jens.wiklander@linaro.org> | 2018-11-20 09:56:58 +0100 |
---|---|---|
committer | Jérôme Forissier <jerome.forissier@linaro.org> | 2019-01-21 18:28:37 +0100 |
commit | d5c5b0b77b2b589666024d219a8007b3f5b6faeb (patch) | |
tree | d006445eba5d16fbc467455fa57de64edd050a36 /core/tee | |
parent | c6edc12acd490e272aade091b5f2389eba37bb33 (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.c | 18 |
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)) { |