Skip to content
Permalink
Browse files

core: scrub user-tainted memory returned by alloc_temp_sec_mem()

This is a security fix for TA-to-TA calls.

In syscall_open_ta_session() and syscall_invoke_ta_command(), caller TA
can reference some private memory, in which case the kernel makes a
temporary copy. Unfortunately, memory allocated through
alloc_temp_sec_mem() is not cleared when returned. One could leverage
this to copy arbitrary data into this secure memory pool or to snoop
former data from a previous call done by another TA (e.g., using
TEE_PARAM_TYPE_MEMREF_OUTPUT allows to map the data while not overwriting
it, hence accessing to what is already there).

This patch introduces mobj_free_wipe() to clear and free an mobj.

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reported-by: Bastien Simondi <bsimondi@netflix.com> [1.5]
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
  • Loading branch information...
jforissier committed Jan 30, 2019
1 parent 7c8b181 commit 934885496e6db0b7c4c8ca28a1aee6696dcc72a6
Showing with 12 additions and 2 deletions.
  1. +10 −0 core/arch/arm/include/mm/mobj.h
  2. +2 −2 core/tee/tee_svc.c
@@ -9,6 +9,7 @@
#include <compiler.h>
#include <mm/core_memprot.h>
#include <mm/fobj.h>
#include <string_ext.h>
#include <sys/queue.h>
#include <tee_api_types.h>
#include <types_ext.h>
@@ -77,6 +78,15 @@ static inline void mobj_free(struct mobj *mobj)
mobj->ops->free(mobj);
}

static inline void mobj_free_wipe(struct mobj *mobj)
{
void *buf = mobj_get_va(mobj, 0);

if (buf)
memzero_explicit(buf, mobj->size);
mobj_free(mobj);
}

static inline uint64_t mobj_get_cookie(struct mobj *mobj)
{
if (mobj && mobj->ops && mobj->ops->get_cookie)
@@ -787,7 +787,7 @@ TEE_Result syscall_open_ta_session(const TEE_UUID *dest,
res = tee_svc_update_out_param(param, tmp_buf_va, usr_param);

function_exit:
mobj_free(mobj_param);
mobj_free_wipe(mobj_param);
if (res == TEE_SUCCESS)
tee_svc_copy_to_user(ta_sess, &s->id, sizeof(s->id));
tee_svc_copy_to_user(ret_orig, &ret_o, sizeof(ret_o));
@@ -876,7 +876,7 @@ TEE_Result syscall_invoke_ta_command(unsigned long ta_sess,

function_exit:
tee_ta_put_session(called_sess);
mobj_free(mobj_param);
mobj_free_wipe(mobj_param);
if (ret_orig)
tee_svc_copy_to_user(ret_orig, &ret_o, sizeof(ret_o));
return res;

0 comments on commit 9348854

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