diff options
author | Jelle Sels <jelle.sels@arm.com> | 2020-09-08 10:56:36 +0200 |
---|---|---|
committer | Jun Nie <jun.nie@linaro.org> | 2021-04-12 09:55:17 +0800 |
commit | 0b1cda9d39e9192e2f8baddbb8812125a277eb57 (patch) | |
tree | aa3e3d94078eb0c5ea2b314b9ad9cac979a543b5 | |
parent | 5ec48ba8c48aa8171288b0d2c8f0027da066aa51 (diff) |
SPM: Put SP in dead state after panic
Make sure that we cannot detect or communicate with a SP after it
has panicked. We also remove all of its memory sharings.
Change-Id: I41008ccf01b22be4e59f6eeaf9ae896d5c1f439b
Signed-off-by: Jelle Sels <jelle.sels@arm.com>
-rw-r--r-- | core/arch/arm/include/kernel/sp.h | 2 | ||||
-rw-r--r-- | core/arch/arm/kernel/ffa_sp.c | 9 | ||||
-rw-r--r-- | core/arch/arm/kernel/sp.c | 24 |
3 files changed, 30 insertions, 5 deletions
diff --git a/core/arch/arm/include/kernel/sp.h b/core/arch/arm/include/kernel/sp.h index 1fa26f585..d198f738f 100644 --- a/core/arch/arm/include/kernel/sp.h +++ b/core/arch/arm/include/kernel/sp.h @@ -57,7 +57,7 @@ struct shared_mem { SLIST_HEAD(mem_head_t, sp_shared_mem) sp_head; }; -enum sp_status {sp_idle, sp_busy, sp_preempted}; +enum sp_status {sp_idle, sp_busy, sp_preempted, sp_dead}; struct sp_session { TAILQ_ENTRY(sp_session) link; TAILQ_ENTRY(sp_session) link_tsd; diff --git a/core/arch/arm/kernel/ffa_sp.c b/core/arch/arm/kernel/ffa_sp.c index daea6d354..689672ebc 100644 --- a/core/arch/arm/kernel/ffa_sp.c +++ b/core/arch/arm/kernel/ffa_sp.c @@ -49,6 +49,8 @@ void ffa_wait(struct thread_smc_args *args, uint16_t caller_id) static uint32_t ffa_get_dst(struct thread_smc_args *args, uint16_t caller_id, uint16_t *dst) { + struct sp_session *s = NULL; + if (args->a2 != 0) { /* a2 should always be 0 */ ffa_send_error(args, FFA_INVALID_PARAMETERS, caller_id); @@ -71,7 +73,12 @@ static uint32_t ffa_get_dst(struct thread_smc_args *args, uint16_t caller_id, return TEE_ERROR_BAD_PARAMETERS; } - if (sp_get_session(FFA_DST(args->a1))) { + s = sp_get_session(FFA_DST(args->a1)); + if (s) { + if (s->state == sp_dead) { + EMSG("Trying to send a message to a dead SP"); + return TEE_ERROR_TARGET_DEAD; + } *dst = FFA_DST(args->a1); } else { /* diff --git a/core/arch/arm/kernel/sp.c b/core/arch/arm/kernel/sp.c index e13322c71..306d78f8b 100644 --- a/core/arch/arm/kernel/sp.c +++ b/core/arch/arm/kernel/sp.c @@ -193,8 +193,11 @@ TEE_Result sp_get_session_id(const TEE_UUID *uuid, uint32_t *session_id) TAILQ_FOREACH(sp_s, &tee_open_sp_sessions, link) { if (!memcmp(&sp_s->s->ctx->uuid, uuid, sizeof(*uuid))) { - *session_id = sp_s->s->id; - return TEE_SUCCESS; + if (sp_s->state != sp_dead) { + *session_id = sp_s->s->id; + return TEE_SUCCESS; + } + return TEE_ERROR_TARGET_DEAD; } } @@ -292,6 +295,19 @@ TEE_Result sp_unmap_regions(struct sp_session *sp_s, struct sp_shared_mem *m) return res; } +static void sp_release_all_mem(struct sp_session *sp_s) +{ + struct sp_shared_mem *m = NULL; + + SLIST_FOREACH(m, &sp_s->mem_head, link) { + m->counter = 0; + sp_unmap_regions(sp_s, m); + SLIST_REMOVE(&sp_s->mem_head, m, sp_shared_mem, link); + m->access_descr->mem_access_perm_descr.endpoint_id = 0; + + free(m); + } +} static TEE_Result sp_init_set_registers(struct sp_session *sp_s) { struct user_ta_ctx *utc = to_user_ta_ctx(sp_s->s->ctx); @@ -389,12 +405,14 @@ uint32_t sp_thread(uint64_t session_id, uint64_t src_id, } set_invoke_timeout(sp_s->s, TEE_TIMEOUT_INFINITE); - res = sp_enter_invoke_cmd(sp_s, 0, NULL, &err_orig); if (sp_s->s->ctx->panicked) { err_orig = TEE_ORIGIN_TEE; + sp_s->state = sp_dead; + sp_release_all_mem(sp_s); + tee_ta_clear_busy(sp_s->s->ctx); destroy_ta_ctx_from_session(sp_s->s); ffa_send_error(args, FFA_DENIED, src_id); return TEE_ERROR_TARGET_DEAD; |