summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelle Sels <jelle.sels@arm.com>2020-09-08 10:56:36 +0200
committerJun Nie <jun.nie@linaro.org>2021-04-12 09:55:17 +0800
commit0b1cda9d39e9192e2f8baddbb8812125a277eb57 (patch)
treeaa3e3d94078eb0c5ea2b314b9ad9cac979a543b5
parent5ec48ba8c48aa8171288b0d2c8f0027da066aa51 (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.h2
-rw-r--r--core/arch/arm/kernel/ffa_sp.c9
-rw-r--r--core/arch/arm/kernel/sp.c24
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;