Skip to content

Commit

Permalink
Fix Shared Memory protection
Browse files Browse the repository at this point in the history
Shared Memory allocation and deallocation is currently
unsufficientlmy guarded. This is fixed in this patch.

Reviewed-by: Jens Wiklander <[email protected]>
Tested-by: Pascal Brand <[email protected]> (STM)
Signed-off-by: Pascal Brand <[email protected]>
  • Loading branch information
Pascal Brand committed Dec 17, 2015
1 parent 4999cdf commit f8189e2
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 17 deletions.
6 changes: 2 additions & 4 deletions core/tee_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,8 @@ static void _tee_context_do_release(struct kref *kref)

dev_dbg(_DEV(tee), "%s: > ctx=%p\n", __func__, ctx);

mutex_lock(&tee->lock);
tee_dec_stats(&tee->stats[TEE_STATS_CONTEXT_IDX]);
list_del(&ctx->entry);
mutex_unlock(&tee->lock);

devm_kfree(_DEV(tee), ctx);
tee_put(tee);
Expand All @@ -202,10 +200,8 @@ static int is_in_list(struct tee *tee, struct list_head *entry)
{
int present = 1;

mutex_lock(&tee->lock);
if ((entry->next == LIST_POISON1) && (entry->prev == LIST_POISON2))
present = 0;
mutex_unlock(&tee->lock);
return present;
}

Expand Down Expand Up @@ -245,7 +241,9 @@ void tee_context_destroy(struct tee_context *ctx)

dev_dbg(_DEV(tee), "%s: ctx=%p\n", __func__, ctx);

mutex_lock(&tee->lock);
tee_context_put(ctx);
mutex_unlock(&tee->lock);
}

int tee_context_copy_from_client(const struct tee_context *ctx,
Expand Down
5 changes: 3 additions & 2 deletions core/tee_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,11 +388,11 @@ int tee_session_close_and_destroy(struct tee_session *sess)
mutex_lock(&sess->ctx->tee->lock);
tee_dec_stats(&tee->stats[TEE_STATS_SESSION_IDX]);
list_del(&sess->entry);
mutex_unlock(&sess->ctx->tee->lock);

devm_kfree(_DEV(tee), sess);
tee_context_put(ctx);
tee_put(tee);
mutex_unlock(&sess->ctx->tee->lock);

dev_dbg(_DEV(tee), "%s: <\n", __func__);
return ret;
Expand Down Expand Up @@ -426,20 +426,21 @@ struct tee_session *tee_session_create_and_open(struct tee_context *ctx,
sess->ctx = ctx;

ret = tee_session_open_be(sess, cmd_io);
mutex_lock(&tee->lock);
if (ret || !sess->sessid || cmd_io->err) {
dev_err(_DEV(tee), "%s: ERROR ret=%d (err=0x%08x, org=%d, sessid=0x%08x)\n",
__func__, ret, cmd_io->err,
cmd_io->origin, sess->sessid);
tee_put(tee);
tee_context_put(ctx);
devm_kfree(_DEV(tee), sess);
mutex_unlock(&tee->lock);
if (ret)
return ERR_PTR(ret);
else
return NULL;
}

mutex_lock(&tee->lock);
tee_inc_stats(&tee->stats[TEE_STATS_SESSION_IDX]);
list_add_tail(&sess->entry, &ctx->list_sess);
mutex_unlock(&tee->lock);
Expand Down
30 changes: 19 additions & 11 deletions core/tee_shm.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,21 @@ struct tee_shm *tee_shm_alloc_from_rpc(struct tee *tee, size_t size)

INMSG();

mutex_lock(&tee->lock);
shm = tee_shm_alloc(tee, size, TEE_SHM_TEMP | TEE_SHM_FROM_RPC);
if (IS_ERR_OR_NULL(shm)) {
dev_err(_DEV(tee), "%s: buffer allocation failed (%ld)\n",
__func__, PTR_ERR(shm));
goto out;
}

mutex_lock(&tee->lock);
tee_inc_stats(&tee->stats[TEE_STATS_SHM_IDX]);
list_add_tail(&shm->entry, &tee->list_rpc_shm);
mutex_unlock(&tee->lock);

shm->ctx = NULL;

out:
mutex_unlock(&tee->lock);
OUTMSGX(shm);
return shm;
}
Expand All @@ -66,14 +67,14 @@ void tee_shm_free_from_rpc(struct tee_shm *shm)
if (shm == NULL)
return;

mutex_lock(&shm->tee->lock);
if (shm->ctx == NULL) {
mutex_lock(&shm->tee->lock);
tee_dec_stats(&shm->tee->stats[TEE_STATS_SHM_IDX]);
list_del(&shm->entry);
mutex_unlock(&shm->tee->lock);
}

tee_shm_free(shm);
mutex_unlock(&shm->tee->lock);
}

struct tee_shm *tee_shm_alloc(struct tee *tee, size_t size, uint32_t flags)
Expand Down Expand Up @@ -398,11 +399,13 @@ int tee_shm_alloc_io(struct tee_context *ctx, struct tee_shm_io *shm_io)
if (ctx->usr_client)
shm_io->fd_shm = 0;

mutex_lock(&tee->lock);
shm = tee_shm_alloc(tee, shm_io->size, shm_io->flags);
if (IS_ERR_OR_NULL(shm)) {
dev_err(_DEV(tee), "%s: buffer allocation failed (%ld)\n",
__func__, PTR_ERR(shm));
return PTR_ERR(shm);
ret = PTR_ERR(shm);
goto out;
}

if (ctx->usr_client) {
Expand All @@ -422,11 +425,10 @@ int tee_shm_alloc_io(struct tee_context *ctx, struct tee_shm_io *shm_io)
BUG_ON(ret); /* tee_core_get must not issue */
tee_context_get(ctx);

mutex_lock(&tee->lock);
tee_inc_stats(&tee->stats[TEE_STATS_SHM_IDX]);
list_add_tail(&shm->entry, &ctx->list_shm);
mutex_unlock(&tee->lock);
out:
mutex_unlock(&tee->lock);
OUTMSG(ret);
return ret;
}
Expand All @@ -440,13 +442,13 @@ void tee_shm_free_io(struct tee_shm *shm)
mutex_lock(&ctx->tee->lock);
tee_dec_stats(&tee->stats[TEE_STATS_SHM_IDX]);
list_del(&shm->entry);
mutex_unlock(&ctx->tee->lock);

tee_shm_free(shm);
tee_put(ctx->tee);
tee_context_put(ctx);
if (dev)
put_device(dev);
mutex_unlock(&ctx->tee->lock);
}

/* Buffer allocated by rpc from fw and to be accessed by the user
Expand All @@ -462,6 +464,7 @@ int tee_shm_fd_for_rpc(struct tee_context *ctx, struct tee_shm_io *shm_io)

shm_io->fd_shm = 0;

mutex_lock(&tee->lock);
if (!list_empty(&tee->list_rpc_shm)) {
list_for_each(pshm, &tee->list_rpc_shm) {
shm = list_entry(pshm, struct tee_shm, entry);
Expand All @@ -482,9 +485,7 @@ int tee_shm_fd_for_rpc(struct tee_context *ctx, struct tee_shm_io *shm_io)
}

shm->ctx = ctx;
mutex_lock(&tee->lock);
list_move(&shm->entry, &ctx->list_shm);
mutex_unlock(&tee->lock);

shm->dev = get_device(_DEV(tee));
ret = tee_get(tee);
Expand All @@ -493,6 +494,7 @@ int tee_shm_fd_for_rpc(struct tee_context *ctx, struct tee_shm_io *shm_io)

BUG_ON(!tee->ops->shm_inc_ref(shm));
out:
mutex_unlock(&tee->lock);
OUTMSG(ret);
return ret;
}
Expand Down Expand Up @@ -719,10 +721,12 @@ struct tee_shm *tee_shm_get(struct tee_context *ctx, TEEC_SharedMemory *c_shm,
dev_dbg(_DEV(tee), "%s: > fd=%d flags=%08x\n",
__func__, c_shm->d.fd, c_shm->flags);

mutex_lock(&tee->lock);
shm = kzalloc(sizeof(*shm), GFP_KERNEL);
if (IS_ERR_OR_NULL(shm)) {
dev_err(_DEV(tee), "can't alloc tee_shm\n");
return ERR_PTR(-ENOMEM);
ret = -ENOMEM;
goto err;
}

shm->ctx = ctx;
Expand Down Expand Up @@ -770,11 +774,13 @@ struct tee_shm *tee_shm_get(struct tee_context *ctx, TEEC_SharedMemory *c_shm,
#endif
}

mutex_unlock(&tee->lock);
OUTMSGX(shm);
return shm;

err:
kfree(shm);
mutex_unlock(&tee->lock);
OUTMSGX(ERR_PTR(ret));
return ERR_PTR(ret);
}
Expand All @@ -789,6 +795,7 @@ void tee_shm_put(struct tee_context *ctx, struct tee_shm *shm)
BUG_ON(!shm);
BUG_ON(!(shm->flags & TEE_SHM_MEMREF));

mutex_lock(&tee->lock);
if (shm->flags & TEEC_MEM_DMABUF) {
struct tee_shm_dma_buf *sdb;
struct dma_buf *dma_buf;
Expand All @@ -807,6 +814,7 @@ void tee_shm_put(struct tee_context *ctx, struct tee_shm *shm)
}

kfree(shm);
mutex_unlock(&tee->lock);
OUTMSG(0);
}

0 comments on commit f8189e2

Please sign in to comment.