Skip to content

Commit

Permalink
core: verify size of allocated shared memory
Browse files Browse the repository at this point in the history
Makes sure that normal world cannot change the size of allocated shared
memory, resulting in a smaller buffer being allocated.

This reintroduces cc6bc5f ("core: verify size of allocated shared
memory") which was lost with Fixes: 2786f14 ("core: thread:
separate old SMC interface handling"). In addition is the READ_ONCE()
macro is used when reading the returned size from non-secure shared
memory.

Since then we have a separate set of functions to deal with RPC when
communicating with FF-A. A corresponding size check is added for the
FF-A version of thread_rpc_alloc().

Reported-by: Patrik Lantz <patrik.lantz@axis.com>
Reviewed-by: Patrik Lantz <patrik.lantz@axis.com>
Acked-by: Jerome Forissier <jerome@forissier.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
  • Loading branch information
jenswi-linaro authored and jforissier committed Nov 17, 2021
1 parent 36ebac6 commit 4ed4502
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
8 changes: 5 additions & 3 deletions core/arch/arm/kernel/thread_optee_smc.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ static void thread_rpc_free(unsigned int bt, uint64_t cookie, struct mobj *mobj)
}

static struct mobj *get_rpc_alloc_res(struct optee_msg_arg *arg,
unsigned int bt)
unsigned int bt, size_t size)
{
struct mobj *mobj = NULL;
uint64_t cookie = 0;
Expand All @@ -547,8 +547,10 @@ static struct mobj *get_rpc_alloc_res(struct optee_msg_arg *arg,
return NULL;

p = arg->params[0].u.tmem.buf_ptr;
sz = arg->params[0].u.tmem.size;
sz = READ_ONCE(arg->params[0].u.tmem.size);
cookie = arg->params[0].u.tmem.shm_ref;
if (sz < size)
return NULL;

if (arg->params[0].attr == OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT)
mobj = rpc_shm_mobj_alloc(p, sz, cookie);
Expand Down Expand Up @@ -589,7 +591,7 @@ static struct mobj *thread_rpc_alloc(size_t size, size_t align, unsigned int bt)
reg_pair_from_64(carg, rpc_args + 1, rpc_args + 2);
thread_rpc(rpc_args);

return get_rpc_alloc_res(arg, bt);
return get_rpc_alloc_res(arg, bt, size);
}

struct mobj *thread_rpc_alloc_payload(size_t size)
Expand Down
6 changes: 6 additions & 0 deletions core/arch/arm/kernel/thread_spmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,12 @@ static struct mobj *thread_rpc_alloc(size_t size, size_t align, unsigned int bt)

assert(mobj_is_nonsec(mobj));

if (mobj->size < size) {
DMSG("Mobj %#"PRIx64": wrong size", cookie);
mobj_put(mobj);
return NULL;
}

if (mobj_inc_map(mobj)) {
DMSG("mobj_inc_map(%#"PRIx64"): failed", cookie);
mobj_put(mobj);
Expand Down

0 comments on commit 4ed4502

Please sign in to comment.