Stack_seal_mitigation: Seal stack for interrupt deprivileging
Seal the handler mode stack (MSP) in case of interrupt deprivileging
for Function mode. The interrupt deprivileging is acheived by the ISR
calling an SVC and a seal is applied on MSP before the interrupt is
deprivileged. Other exceptions such as faults runs to panic so there
is no need of sealing caller contexts for these exceptions.
This patch also removes the separate inline assembly implementation for
Mainline as the benefit of a single code to maintain and patch far
outweigh any benefits gained by a separate implementation.
Change-Id: I8fdff140f4157882853e3abd24cc23b7e68ee0a3
Signed-off-by: Ken Liu <ken.liu@arm.com>
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
diff --git a/secure_fw/spm/arch/tfm_arch_v8m_base.c b/secure_fw/spm/arch/tfm_arch_v8m_base.c
index 0c5d834..2664daa 100644
--- a/secure_fw/spm/arch/tfm_arch_v8m_base.c
+++ b/secure_fw/spm/arch/tfm_arch_v8m_base.c
@@ -198,17 +198,38 @@
__attribute__((naked)) void SVC_Handler(void)
{
__ASM volatile(
+#if !defined(__ICCARM__)
+ ".syntax unified \n"
+#endif
+ "MRS r0, PSP \n"
"MRS r2, MSP \n"
"MOVS r1, #4 \n"
"MOV r3, lr \n"
- "MOV r0, r2 \n"
"TST r1, r3 \n"
- "BEQ handler \n"
- /* If SVC was made from thread mode, overwrite r0 with PSP */
- "MRS r0, PSP \n"
- "handler: \n"
+ "BNE from_thread \n"
+ /*
+ * This branch is taken when the code is being invoked from handler mode.
+ * This happens when a de-privileged interrupt handler is to be run. Seal
+ * the stack before de-privileging.
+ */
+ "LDR r0, =0xFEF5EDA5 \n"
+ "MOVS r3, r0 \n"
+ "PUSH {r0, r3} \n"
+ /* Overwrite r0 with MSP */
+ "MOV r0, r2 \n"
+ "from_thread: \n"
"MOV r1, lr \n"
"BL tfm_core_svc_handler \n"
+ "MOVS r1, #4 \n"
+ "TST r1, r0 \n"
+ "BNE to_thread \n"
+ /*
+ * This branch is taken when the code is going to return to handler mode.
+ * This happens after a de-privileged interrupt handler had been run. Pop
+ * the sealing from the stack.
+ */
+ "POP {r1, r2} \n"
+ "to_thread: \n"
"BX r0 \n"
);
}
diff --git a/secure_fw/spm/arch/tfm_arch_v8m_main.c b/secure_fw/spm/arch/tfm_arch_v8m_main.c
index be268ec..cb99b20 100644
--- a/secure_fw/spm/arch/tfm_arch_v8m_main.c
+++ b/secure_fw/spm/arch/tfm_arch_v8m_main.c
@@ -193,14 +193,38 @@
__attribute__((naked)) void SVC_Handler(void)
{
__ASM volatile(
+#if !defined(__ICCARM__)
+ ".syntax unified \n"
+#endif
+ "MRS r0, PSP \n"
"MRS r2, MSP \n"
- /* Check store SP in thread mode to r0 */
- "TST lr, #4 \n"
- "ITE EQ \n"
- "MOVEQ r0, r2 \n"
- "MRSNE r0, PSP \n"
+ "MOVS r1, #4 \n"
+ "MOV r3, lr \n"
+ "TST r1, r3 \n"
+ "BNE from_thread \n"
+ /*
+ * This branch is taken when the code is being invoked from handler mode.
+ * This happens when a de-privileged interrupt handler is to be run. Seal
+ * the stack before de-privileging.
+ */
+ "LDR r0, =0xFEF5EDA5 \n"
+ "MOVS r3, r0 \n"
+ "PUSH {r0, r3} \n"
+ /* Overwrite r0 with MSP */
+ "MOV r0, r2 \n"
+ "from_thread: \n"
"MOV r1, lr \n"
"BL tfm_core_svc_handler \n"
+ "MOVS r1, #4 \n"
+ "TST r1, r0 \n"
+ "BNE to_thread \n"
+ /*
+ * This branch is taken when the code is going to return to handler mode.
+ * This happens after a de-privileged interrupt handler had been run. Pop
+ * the sealing from the stack.
+ */
+ "POP {r1, r2} \n"
+ "to_thread: \n"
"BX r0 \n"
);
}
diff --git a/secure_fw/spm/model_func/spm_func.c b/secure_fw/spm/model_func/spm_func.c
index 96d90de..6b8575f 100644
--- a/secure_fw/spm/model_func/spm_func.c
+++ b/secure_fw/spm/model_func/spm_func.c
@@ -933,8 +933,12 @@
uint32_t tfm_spm_depriv_return_handler(uint32_t *irq_svc_args, uint32_t lr)
{
enum tfm_status_e res;
- struct tfm_state_context_t *irq_svc_ctx =
- (struct tfm_state_context_t *)irq_svc_args;
+ struct tfm_state_context_t *irq_svc_ctx;
+
+ /* Take into account the sealed stack*/
+ irq_svc_args += 2;
+
+ irq_svc_ctx = (struct tfm_state_context_t *)irq_svc_args;
if (!(lr & EXC_RETURN_STACK_PROCESS)) {
/* Partition request SVC called with MSP active.