Stack_seal_mitigation: Seal the PSP stacks for Library mode.
This patch does the changes for sealing the PSP stacks used
in library mode. There are 2 stacks used as PSP in Library mode :
ARM_LIB_STACK and TFM_SECURE_STACK. In case of ARM_LIB_STACK,
a new section is created for sealing the stack. The TFM_SECURE_STACK
needs more careful manipulation as the top of stack is used for iovec
parameters. So the code inserts a stack seal between the iovec
parameters and Partition stack area.
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
Change-Id: I028c625e53a8bb1677a7f3001095ab3452f82c32
diff --git a/secure_fw/spm/cmsis_func/spm_func.c b/secure_fw/spm/cmsis_func/spm_func.c
index 4c91018..7c2f468 100644
--- a/secure_fw/spm/cmsis_func/spm_func.c
+++ b/secure_fw/spm/cmsis_func/spm_func.c
@@ -17,6 +17,7 @@
#include "tfm_peripherals_def.h"
#include "tfm_secure_api.h"
#include "tfm_spm_hal.h"
+#include "tfm_core_trustzone.h"
#include "spm_func.h"
#include "region_defs.h"
#include "region.h"
@@ -32,9 +33,54 @@
#error TFM_LVL is not defined!
#endif
+#ifdef TFM_MULTI_CORE_TOPOLOGY
+#error Multi core is not supported by Function mode
+#endif
+
REGION_DECLARE_T(Image$$, TFM_SECURE_STACK, $$ZI$$Base, uint32_t);
REGION_DECLARE_T(Image$$, TFM_SECURE_STACK, $$ZI$$Limit, struct iovec_args_t)[];
+static uint32_t *tfm_secure_stack_seal =
+ ((uint32_t *)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit)[-1]) - 2;
+
+REGION_DECLARE_T(Image$$, ARM_LIB_STACK_SEAL, $$ZI$$Base, uint32_t);
+
+/*
+ * Function to seal the psp stacks for Function model of TF-M.
+ */
+void tfm_spm_seal_psp_stacks(void)
+{
+ /*
+ * The top of TFM_SECURE_STACK is used for iovec parameters, we need to
+ * place the seal between iovec parameters and partition stack.
+ *
+ * Image$$TFM_SECURE_STACK$$ZI$$Limit-> +-------------------------+
+ * | |
+ * | iovec parameters for |
+ * | partition |
+ * (Image$$TFM_SECURE_STACK$$ZI$$Limit -| |
+ * sizeof(iovec_args_t)) -> +-------------------------+
+ * | Stack Seal |
+ * +-------------------------+
+ * | |
+ * | Partition stack |
+ * | |
+ * Image$$TFM_SECURE_STACK$$ZI$$Base-> +-------------------------+
+ */
+ *(tfm_secure_stack_seal) = TFM_STACK_SEAL_VALUE;
+ *(tfm_secure_stack_seal + 1) = TFM_STACK_SEAL_VALUE;
+
+ /*
+ * Seal the ARM_LIB_STACK by writing the seal value to the reserved
+ * region.
+ */
+ uint32_t *arm_lib_stck_seal_base = (uint32_t *)®ION_NAME(Image$$,
+ ARM_LIB_STACK_SEAL, $$ZI$$Base);
+
+ *(arm_lib_stck_seal_base) = TFM_STACK_SEAL_VALUE;
+ *(arm_lib_stck_seal_base + 1) = TFM_STACK_SEAL_VALUE;
+}
+
/*
* This is the "Big Lock" on the secure side, to guarantee single entry
* to SPE
@@ -406,11 +452,11 @@
/* Prepare switch to shared secure partition stack */
/* In case the call is coming from the non-secure world, we save the iovecs
- * on the stop of the stack. So the memory area, that can actually be used
- * as stack by the partitions starts at a lower address
+ * on the stop of the stack. Also the stack seal is present below this region.
+ * So the memory area, that can actually be used as stack by the partitions
+ * starts at a lower address.
*/
- partition_psp =
- (uint32_t)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit)[-1];
+ partition_psp = (uint32_t) tfm_secure_stack_seal;
partition_psplim =
(uint32_t)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Base);