From 941a58d78c99c4754fbd4ec3079ec9e1d596af8f Mon Sep 17 00:00:00 2001
From: Jens Wiklander <jens.wiklander@linaro.org>
Date: Fri, 4 Apr 2025 10:24:34 +0200
Subject: [PATCH] Add optee.ta.instanceKeepCrashed property

Add the optee.ta.instanceKeepCrashed property to prevent a TA with
gpd.ta.instanceKeepAlive=true to be restarted. This prevents unexpected
resetting of the state of the TA.

Upstream-Status: Backport
CVE: CVE-2025-46733
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Alex Lewontin <alex.lewontin@canonical.com>
Reviewed-by: Etienne Carriere <etienne.carriere@foss.st.com>
---
 core/kernel/tee_ta_manager.c         | 10 +++++++---
 lib/libutee/include/user_ta_header.h |  8 +++++++-
 ta/user_ta_header.c                  |  3 +++
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/core/kernel/tee_ta_manager.c b/core/kernel/tee_ta_manager.c
index e4740468873..75e55a8e475 100644
--- a/core/kernel/tee_ta_manager.c
+++ b/core/kernel/tee_ta_manager.c
@@ -455,6 +455,7 @@ TEE_Result tee_ta_close_session(struct tee_ta_session *csess,
	struct tee_ta_session *sess = NULL;
	struct tee_ta_ctx *ctx = NULL;
	struct ts_ctx *ts_ctx = NULL;
+	bool keep_crashed = false;
	bool keep_alive = false;

	DMSG("csess 0x%" PRIxVA " id %u",
@@ -501,9 +502,12 @@ TEE_Result tee_ta_close_session(struct tee_ta_session *csess,
		panic();

	ctx->ref_count--;
-	keep_alive = (ctx->flags & TA_FLAG_INSTANCE_KEEP_ALIVE) &&
-			(ctx->flags & TA_FLAG_SINGLE_INSTANCE);
-	if (!ctx->ref_count && (ctx->panicked || !keep_alive)) {
+	if (ctx->flags & TA_FLAG_SINGLE_INSTANCE)
+		keep_alive = ctx->flags & TA_FLAG_INSTANCE_KEEP_ALIVE;
+	if (keep_alive)
+		keep_crashed = ctx->flags & TA_FLAG_INSTANCE_KEEP_CRASHED;
+	if (!ctx->ref_count &&
+	    ((ctx->panicked && !keep_crashed) || !keep_alive)) {
		if (!ctx->is_releasing) {
			TAILQ_REMOVE(&tee_ctxes, ctx, link);
			ctx->is_releasing = true;
diff --git a/lib/libutee/include/user_ta_header.h b/lib/libutee/include/user_ta_header.h
index 0336c64b2f7..c5622982f2e 100644
--- a/lib/libutee/include/user_ta_header.h
+++ b/lib/libutee/include/user_ta_header.h
@@ -52,8 +52,13 @@
					BIT32(11)
 #define TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE	\
					BIT32(12) /* with TEE_STORAGE_PRIVATE */
+/*
+ * Don't restart a TA with TA_FLAG_INSTANCE_KEEP_ALIVE set if it has
+ * crashed.
+ */
+#define TA_FLAG_INSTANCE_KEEP_CRASHED	BIT32(13)

-#define TA_FLAGS_MASK			GENMASK_32(12, 0)
+#define TA_FLAGS_MASK			GENMASK_32(13, 0)

 struct ta_head {
	TEE_UUID uuid;
@@ -133,6 +138,7 @@ extern struct __elf_phdr_info __elf_phdr_info;
 #define TA_PROP_STR_SINGLE_INSTANCE	"gpd.ta.singleInstance"
 #define TA_PROP_STR_MULTI_SESSION	"gpd.ta.multiSession"
 #define TA_PROP_STR_KEEP_ALIVE		"gpd.ta.instanceKeepAlive"
+#define TA_PROP_STR_KEEP_CRASHED	"optee.ta.instanceKeepCrashed"
 #define TA_PROP_STR_DATA_SIZE		"gpd.ta.dataSize"
 #define TA_PROP_STR_STACK_SIZE		"gpd.ta.stackSize"
 #define TA_PROP_STR_VERSION		"gpd.ta.version"
diff --git a/ta/user_ta_header.c b/ta/user_ta_header.c
index 3125af55c44..aa804c1efaa 100644
--- a/ta/user_ta_header.c
+++ b/ta/user_ta_header.c
@@ -142,6 +142,9 @@ const struct user_ta_property ta_props[] = {
	{TA_PROP_STR_KEEP_ALIVE, USER_TA_PROP_TYPE_BOOL,
	 &(const bool){(TA_FLAGS & TA_FLAG_INSTANCE_KEEP_ALIVE) != 0}},

+	{TA_PROP_STR_KEEP_CRASHED, USER_TA_PROP_TYPE_BOOL,
+	 &(const bool){(TA_FLAGS & TA_FLAG_INSTANCE_KEEP_CRASHED) != 0}},
+
	{TA_PROP_STR_DATA_SIZE, USER_TA_PROP_TYPE_U32,
	 &(const uint32_t){TA_DATA_SIZE}},
