forked from espressif/esp-idf
Merge branch 'feat/esp_tee_hw_stack_guard' into 'master'
feat(esp_tee): Support for the RISC-V H/W stack guard with ESP-TEE enabled Closes IDF-10770 and IDF-14350 See merge request espressif/esp-idf!43162
This commit is contained in:
@@ -24,10 +24,14 @@ if(CONFIG_IDF_ENV_FPGA OR CONFIG_ESP_BRINGUP_BYPASS_RANDOM_SETTING)
|
||||
endif()
|
||||
|
||||
if(BOOTLOADER_BUILD OR esp_tee_build)
|
||||
# "_esp_error_check_failed()" requires spi_flash module
|
||||
# Bootloader relies on some Kconfig options defined in esp_system.
|
||||
idf_component_register(SRCS "${srcs}" REQUIRES spi_flash
|
||||
INCLUDE_DIRS include)
|
||||
set(include_dirs "include")
|
||||
if(esp_tee_build)
|
||||
list(APPEND include_dirs "port/include/private")
|
||||
endif()
|
||||
# "_esp_error_check_failed()" requires spi_flash module
|
||||
# Bootloader relies on some Kconfig options defined in esp_system.
|
||||
idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}"
|
||||
REQUIRES spi_flash)
|
||||
else()
|
||||
list(APPEND srcs "crosscore_int.c"
|
||||
"esp_ipc.c"
|
||||
|
||||
@@ -447,8 +447,7 @@ menu "ESP System Settings"
|
||||
|
||||
config ESP_SYSTEM_HW_STACK_GUARD
|
||||
bool "Hardware stack guard"
|
||||
# TODO: [ESP-TEE] IDF-10770
|
||||
depends on SOC_ASSIST_DEBUG_SUPPORTED && !SECURE_ENABLE_TEE
|
||||
depends on SOC_ASSIST_DEBUG_SUPPORTED
|
||||
default y
|
||||
help
|
||||
This config allows to trigger a panic interrupt when Stack Pointer register goes out of allocated stack
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -39,10 +39,10 @@ uint32_t esp_hw_stack_guard_get_pc(uint32_t core_id);
|
||||
#define ASSIST_DEBUG_CORE_0_SP_MAX_OFFSET (ASSIST_DEBUG_CORE_0_SP_MAX_REG - DR_REG_ASSIST_DEBUG_BASE)
|
||||
#define ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET (ASSIST_DEBUG_CORE_0_MONITOR_REG - DR_REG_ASSIST_DEBUG_BASE)
|
||||
|
||||
.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0 reg1
|
||||
.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0 reg1 sp_min sp_max
|
||||
lui \reg1, ASSIST_DEBUG_CORE_0_MONITOR_REG_IMM
|
||||
sw a0, ASSIST_DEBUG_CORE_0_SP_MIN_OFFSET(\reg1)
|
||||
sw a1, ASSIST_DEBUG_CORE_0_SP_MAX_OFFSET(\reg1)
|
||||
sw \sp_min, ASSIST_DEBUG_CORE_0_SP_MIN_OFFSET(\reg1)
|
||||
sw \sp_max, ASSIST_DEBUG_CORE_0_SP_MAX_OFFSET(\reg1)
|
||||
.endm
|
||||
|
||||
.macro ESP_HW_STACK_GUARD_MONITOR_STOP_CPU0 reg1 reg2
|
||||
@@ -59,6 +59,18 @@ ori \reg2, \reg2, ASSIST_DEBUG_SP_SPILL_BITS
|
||||
sw \reg2, ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET(\reg1)
|
||||
.endm
|
||||
|
||||
.macro ESP_HW_STACK_GUARD_GET_BOUNDS_CPU0 reg1 sp_min sp_max
|
||||
lui \reg1, ASSIST_DEBUG_CORE_0_MONITOR_REG_IMM
|
||||
lw \sp_min, ASSIST_DEBUG_CORE_0_SP_MIN_OFFSET(\reg1)
|
||||
lw \sp_max, ASSIST_DEBUG_CORE_0_SP_MAX_OFFSET(\reg1)
|
||||
.endm
|
||||
|
||||
.macro ESP_HW_STACK_GUARD_MONITOR_QUERY_CPU0 reg1 reg2
|
||||
lui \reg1, ASSIST_DEBUG_CORE_0_MONITOR_REG_IMM
|
||||
lw \reg2, ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET(\reg1)
|
||||
andi \reg2, \reg2, ASSIST_DEBUG_SP_SPILL_BITS
|
||||
.endm
|
||||
|
||||
#if SOC_CPU_CORES_NUM > 1
|
||||
|
||||
#define ASSIST_DEBUG_CORE_1_MONITOR_REG_IMM (ASSIST_DEBUG_CORE_1_MONITOR_REG >> 12)
|
||||
@@ -66,10 +78,10 @@ sw \reg2, ASSIST_DEBUG_CORE_0_SP_SPILL_OFFSET(\reg1)
|
||||
#define ASSIST_DEBUG_CORE_1_SP_MAX_OFFSET (ASSIST_DEBUG_CORE_1_SP_MAX_REG - DR_REG_ASSIST_DEBUG_BASE)
|
||||
#define ASSIST_DEBUG_CORE_1_SP_SPILL_OFFSET (ASSIST_DEBUG_CORE_1_MONITOR_REG - DR_REG_ASSIST_DEBUG_BASE)
|
||||
|
||||
.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CPU1 reg1
|
||||
.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CPU1 reg1 sp_min sp_max
|
||||
lui \reg1, ASSIST_DEBUG_CORE_1_MONITOR_REG_IMM
|
||||
sw a0, ASSIST_DEBUG_CORE_1_SP_MIN_OFFSET(\reg1)
|
||||
sw a1, ASSIST_DEBUG_CORE_1_SP_MAX_OFFSET(\reg1)
|
||||
sw \sp_min, ASSIST_DEBUG_CORE_1_SP_MIN_OFFSET(\reg1)
|
||||
sw \sp_max, ASSIST_DEBUG_CORE_1_SP_MAX_OFFSET(\reg1)
|
||||
.endm
|
||||
|
||||
.macro ESP_HW_STACK_GUARD_MONITOR_STOP_CPU1 reg1 reg2
|
||||
@@ -86,16 +98,28 @@ ori \reg2, \reg2, ASSIST_DEBUG_SP_SPILL_BITS
|
||||
sw \reg2, ASSIST_DEBUG_CORE_1_SP_SPILL_OFFSET(\reg1)
|
||||
.endm
|
||||
|
||||
.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE reg1
|
||||
.macro ESP_HW_STACK_GUARD_GET_BOUNDS_CPU1 reg1 sp_min sp_max
|
||||
lui \reg1, ASSIST_DEBUG_CORE_1_MONITOR_REG_IMM
|
||||
lw \sp_min, ASSIST_DEBUG_CORE_1_SP_MIN_OFFSET(\reg1)
|
||||
lw \sp_max, ASSIST_DEBUG_CORE_1_SP_MAX_OFFSET(\reg1)
|
||||
.endm
|
||||
|
||||
.macro ESP_HW_STACK_GUARD_MONITOR_QUERY_CPU1 reg1 reg2
|
||||
lui \reg1, ASSIST_DEBUG_CORE_1_MONITOR_REG_IMM
|
||||
lw \reg2, ASSIST_DEBUG_CORE_1_SP_SPILL_OFFSET(\reg1)
|
||||
andi \reg2, \reg2, ASSIST_DEBUG_SP_SPILL_BITS
|
||||
.endm
|
||||
|
||||
.macro ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE reg1 sp_min sp_max
|
||||
/* Check the current core ID */
|
||||
csrr \reg1, mhartid
|
||||
beqz \reg1, 1f
|
||||
/* Core 1 */
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CPU1 \reg1
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CPU1 \reg1 \sp_min \sp_max
|
||||
j 2f
|
||||
1:
|
||||
/* Core 0 */
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0 \reg1
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0 \reg1 \sp_min \sp_max
|
||||
2:
|
||||
.endm
|
||||
|
||||
@@ -125,11 +149,39 @@ ESP_HW_STACK_GUARD_MONITOR_STOP_CPU0 \reg1 \reg2
|
||||
2:
|
||||
.endm
|
||||
|
||||
.macro ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE reg1 sp_min sp_max
|
||||
/* Check the current core ID */
|
||||
csrr \reg1, mhartid
|
||||
beqz \reg1, 1f
|
||||
/* Core 1 */
|
||||
ESP_HW_STACK_GUARD_GET_BOUNDS_CPU1 \reg1 \sp_min \sp_max
|
||||
j 2f
|
||||
1:
|
||||
/* Core 0 */
|
||||
ESP_HW_STACK_GUARD_GET_BOUNDS_CPU0 \reg1 \sp_min \sp_max
|
||||
2:
|
||||
.endm
|
||||
|
||||
.macro ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE reg1 reg2
|
||||
/* Check the current core ID */
|
||||
csrr \reg1, mhartid
|
||||
beqz \reg1, 1f
|
||||
/* Core 1 */
|
||||
ESP_HW_STACK_GUARD_MONITOR_QUERY_CPU1 \reg1 \reg2
|
||||
j 2f
|
||||
1:
|
||||
/* Core 0 */
|
||||
ESP_HW_STACK_GUARD_MONITOR_QUERY_CPU0 \reg1 \reg2
|
||||
2:
|
||||
.endm
|
||||
|
||||
#else // SOC_CPU_CORES_NUM <= 1
|
||||
|
||||
#define ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0
|
||||
#define ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE ESP_HW_STACK_GUARD_MONITOR_START_CPU0
|
||||
#define ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE ESP_HW_STACK_GUARD_MONITOR_STOP_CPU0
|
||||
#define ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE ESP_HW_STACK_GUARD_GET_BOUNDS_CPU0
|
||||
#define ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE ESP_HW_STACK_GUARD_MONITOR_QUERY_CPU0
|
||||
|
||||
#endif // SOC_CPU_CORES_NUM > 1
|
||||
|
||||
|
||||
@@ -688,7 +688,11 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2
|
||||
}
|
||||
|
||||
int cfg_key_id = (int)CONFIG_SECURE_TEE_PBKDF2_EFUSE_HMAC_KEY_ID;
|
||||
if (cfg_key_id < 0 || cfg_key_id >= HMAC_KEY_MAX) {
|
||||
/* Split the checks to keep Coverity happy */
|
||||
if (cfg_key_id < 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (cfg_key_id >= HMAC_KEY_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,13 @@
|
||||
/* The system interrupts are not used for now, so trigger a panic every time one occurs. */
|
||||
#define _system_int_handler _tee_panic_handler
|
||||
|
||||
/* Handlers defined in the `vector.S` file, common to all RISC-V targets */
|
||||
.global _tee_ns_intr_handler
|
||||
.global _tee_panic_handler
|
||||
#define MEMPROT_ISR _tee_ns_intr_handler
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
#define ASTDBG_ISR _tee_panic_handler
|
||||
#else
|
||||
#define ASTDBG_ISR _tee_ns_intr_handler
|
||||
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
|
||||
.section .exception_vectors_table.text
|
||||
|
||||
@@ -32,7 +36,7 @@
|
||||
.type _vector_table, @function
|
||||
.balign 0x40
|
||||
_vector_table:
|
||||
j _tee_panic_handler
|
||||
j _tee_exception_handler
|
||||
.size _vector_table, .-_vector_table
|
||||
|
||||
|
||||
@@ -94,10 +98,8 @@ _mtvt_table:
|
||||
.word _tee_ns_intr_handler /* 39: Free interrupt number */
|
||||
.word _tee_panic_handler /* 40: ETS_INT_WDT_INUM (+16) panic-interrupt (soc-level panic) */
|
||||
.word _tee_panic_handler /* 41: ETS_CACHEERR_INUM (+16) panic-interrupt (soc-level panic) */
|
||||
/* NOTE: Triggers panic irrespective of the Kconfig setting with ESP-TEE */
|
||||
.word _tee_panic_handler /* 42: ETS_MEMPROT_ERR_INUM (+16) handler (soc-level panic) */
|
||||
/* TODO: [IDF-10770] Not supported yet with ESP-TEE */
|
||||
.word _tee_panic_handler /* 43: ETS_ASSIST_DEBUG_INUM (+16) handler (soc-level panic) */
|
||||
.word MEMPROT_ISR /* 42: ETS_MEMPROT_ERR_INUM (+16) handler (soc-level panic) */
|
||||
.word ASTDBG_ISR /* 43: ETS_ASSIST_DEBUG_INUM (+16) handler (soc-level panic) */
|
||||
.word _tee_ns_intr_handler /* 44: ETS_IPC_ISR_INUM (+16) handler*/
|
||||
.word _tee_ns_intr_handler /* 45: Free interrupt number */
|
||||
.word _tee_ns_intr_handler /* 46: ESP-TEE: U-mode interrupt delegation entry */
|
||||
|
||||
@@ -10,10 +10,13 @@
|
||||
#error "ETS_INT_WDT_INUM expected to be 24"
|
||||
#endif
|
||||
|
||||
/* Handlers defined in the `esp_tee_vectors.S` file */
|
||||
.global _tee_panic_handler
|
||||
.global _tee_ns_intr_handler
|
||||
.global _tee_s_intr_handler
|
||||
#define MEMPROT_ISR _tee_ns_intr_handler
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
#define ASTDBG_ISR _tee_panic_handler
|
||||
#else
|
||||
#define ASTDBG_ISR _tee_ns_intr_handler
|
||||
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
|
||||
.section .exception_vectors_table.text, "ax"
|
||||
|
||||
@@ -36,7 +39,7 @@
|
||||
.global _vector_table
|
||||
.type _vector_table, @function
|
||||
_vector_table:
|
||||
j _tee_panic_handler /* 0: Exception entry */
|
||||
j _tee_exception_handler /* 0: Exception entry */
|
||||
/* NOTE: All of the free interrupts are used by the REE */
|
||||
j _tee_ns_intr_handler /* 1: Free interrupt number */
|
||||
j _tee_ns_intr_handler /* 2: Free interrupt number */
|
||||
@@ -63,10 +66,8 @@ _vector_table:
|
||||
j _tee_ns_intr_handler /* 23: Free interrupt number */
|
||||
j _tee_panic_handler /* 24: ETS_INT_WDT_INUM panic-interrupt (soc-level panic) */
|
||||
j _tee_panic_handler /* 25: ETS_CACHEERR_INUM panic-interrupt (soc-level panic) */
|
||||
/* NOTE: Triggers panic irrespective of the Kconfig setting with ESP-TEE */
|
||||
j _tee_panic_handler /* 26: ETS_MEMPROT_ERR_INUM handler (soc-level panic) */
|
||||
/* TODO: [IDF-10770] Not supported yet with ESP-TEE */
|
||||
j _tee_panic_handler /* 27: ETS_ASSIST_DEBUG_INUM handler (soc-level panic) */
|
||||
j MEMPROT_ISR /* 26: ETS_MEMPROT_ERR_INUM handler (soc-level panic) */
|
||||
j ASTDBG_ISR /* 27: ETS_ASSIST_DEBUG_INUM handler (soc-level panic) */
|
||||
j _tee_ns_intr_handler /* 28: Free interrupt number */
|
||||
j _tee_ns_intr_handler /* 29: Free interrupt number */
|
||||
j _tee_ns_intr_handler /* 30: Free interrupt number */
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#include "esp_tee_intr_defs.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
#include "esp_private/hw_stack_guard.h"
|
||||
#endif
|
||||
|
||||
.equ SAVE_REGS, 32
|
||||
.equ CONTEXT_SIZE, (SAVE_REGS * 4)
|
||||
.equ panic_from_exception, tee_panic_from_exc
|
||||
@@ -32,22 +36,99 @@
|
||||
.global _tee_s_entry
|
||||
|
||||
.section .data
|
||||
.balign 4
|
||||
|
||||
.align 4
|
||||
.global _ns_sp
|
||||
_ns_sp:
|
||||
.word 0
|
||||
|
||||
.align 4
|
||||
.global _s_sp
|
||||
_s_sp:
|
||||
.word 0
|
||||
|
||||
.align 4
|
||||
.global _s_intr_thresh
|
||||
_s_intr_thresh:
|
||||
.word 0
|
||||
|
||||
.global _ns_sp_min
|
||||
_ns_sp_min:
|
||||
.word 0
|
||||
|
||||
.global _ns_sp_max
|
||||
_ns_sp_max:
|
||||
.word 0
|
||||
|
||||
/**
|
||||
* STACK_GUARD_PRE_SWITCH
|
||||
* Stops HW stack-guard monitoring and optionally saves current bounds.
|
||||
*
|
||||
* Args:
|
||||
* op_reg – output register for “monitoring enabled” state (must be reused)
|
||||
* to_save – 1=save bounds to memory, 0=skip saving
|
||||
* sp_min – symbol to store lower bound (if to_save=1)
|
||||
* sp_max – symbol to store upper bound (if to_save=1)
|
||||
*
|
||||
* Clobbers: t0, t1, t2, op_reg
|
||||
*/
|
||||
.macro STACK_GUARD_PRE_SWITCH op_reg, to_save, sp_min, sp_max
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* Query if monitoring is enabled: result goes into \op_reg */
|
||||
ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE t2 \op_reg
|
||||
beqz \op_reg, 1f
|
||||
|
||||
.if \to_save
|
||||
/* Save current REE/U-mode stack bounds */
|
||||
ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE t2 t0 t1
|
||||
la t2, \sp_min
|
||||
sw t0, 0(t2)
|
||||
la t2, \sp_max
|
||||
sw t1, 0(t2)
|
||||
.endif
|
||||
|
||||
/* Stop monitoring */
|
||||
ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE t0 t1
|
||||
fence
|
||||
1:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/**
|
||||
* STACK_GUARD_POST_SWITCH
|
||||
* Restores or applies new bounds after switching stacks, then restarts monitoring.
|
||||
*
|
||||
* Args:
|
||||
* op_reg – saved monitoring state from PRE_SWITCH
|
||||
* to_restore – 1=restore from memory, 0=set static bounds
|
||||
* sp_min – saved bound (restore) or static lower bound (S-mode)
|
||||
* sp_max – saved bound (restore) or static upper bound (S-mode)
|
||||
*
|
||||
* Clobbers: t0, t1, t2
|
||||
*/
|
||||
.macro STACK_GUARD_POST_SWITCH op_reg, to_restore, sp_min, sp_max
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* Check if monitoring was enabled (using saved state from op_reg) */
|
||||
beqz \op_reg, 1f
|
||||
|
||||
.if \to_restore
|
||||
/* Restore saved REE/U-mode bounds from memory */
|
||||
la t2, \sp_min
|
||||
lw t0, 0(t2)
|
||||
la t2, \sp_max
|
||||
lw t1, 0(t2)
|
||||
.else
|
||||
/* Use new TEE/S-mode stack bounds (static symbols) */
|
||||
la t0, \sp_min
|
||||
la t1, \sp_max
|
||||
.endif
|
||||
|
||||
/* Apply bounds to hardware stack guard */
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE t2 t0 t1
|
||||
/* Restart monitoring */
|
||||
ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE t0 t1
|
||||
1:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/* Macro which first allocates space on the stack to save general
|
||||
* purpose registers, and then save them. GP register is excluded.
|
||||
* The default size allocated on the stack is CONTEXT_SIZE, but it
|
||||
@@ -179,9 +260,10 @@ _s_intr_thresh:
|
||||
.section .exception_vectors.text, "ax"
|
||||
|
||||
/* Exception handler. */
|
||||
.global _tee_exception_handler
|
||||
.global _tee_panic_handler
|
||||
.type _tee_panic_handler, @function
|
||||
_tee_panic_handler:
|
||||
_tee_exception_handler:
|
||||
/* Backup t0, t1 on the stack before using it */
|
||||
addi sp, sp, -16
|
||||
sw t0, 0(sp)
|
||||
@@ -205,7 +287,7 @@ _tee_panic_handler:
|
||||
lw t1, 4(sp)
|
||||
addi sp, sp, 16
|
||||
|
||||
_actual_panic:
|
||||
_tee_panic_handler:
|
||||
/* Not an ecall, proceed to the panic handler */
|
||||
/* Allocate space on the stack and store general purpose registers */
|
||||
save_general_regs RV_STK_FRMSZ
|
||||
@@ -267,7 +349,7 @@ _return_from_exception:
|
||||
restore_general_regs RV_STK_FRMSZ
|
||||
mret
|
||||
|
||||
.size _tee_panic_handler, .-_tee_panic_handler
|
||||
.size _tee_exception_handler, .-_tee_exception_handler
|
||||
|
||||
/* ECALL handler. */
|
||||
.type _ecall_handler, @function
|
||||
@@ -301,9 +383,13 @@ _1:
|
||||
csrw CSR_MINTTHRESH, t1
|
||||
|
||||
_skip_thresh_restore:
|
||||
STACK_GUARD_PRE_SWITCH t3 0
|
||||
|
||||
/* Switching back to the saved REE stack */
|
||||
la t0, _ns_sp
|
||||
lw sp, 0(t0)
|
||||
|
||||
STACK_GUARD_POST_SWITCH t3 1 _ns_sp_min _ns_sp_max
|
||||
fence
|
||||
|
||||
/* Backup the A0 register
|
||||
@@ -353,9 +439,13 @@ _process_ecall:
|
||||
la t0, _ns_sp
|
||||
sw sp, 0(t0)
|
||||
|
||||
STACK_GUARD_PRE_SWITCH t3 1 _ns_sp_min _ns_sp_max
|
||||
|
||||
/* Switch to the M-mode (i.e. TEE) stack */
|
||||
la sp, _tee_stack
|
||||
|
||||
STACK_GUARD_POST_SWITCH t3 0 _tee_stack_bottom _tee_stack
|
||||
|
||||
/* Load the TEE entry point (see _tee_s_entry) in the mepc */
|
||||
la t0, _tee_s_entry
|
||||
csrw mepc, t0
|
||||
@@ -389,10 +479,14 @@ _3:
|
||||
lw t2, 0(t0)
|
||||
bne t2, t1, _3
|
||||
|
||||
STACK_GUARD_PRE_SWITCH t3 0
|
||||
|
||||
/* Restore the secure stack pointer */
|
||||
la t0, _s_sp
|
||||
lw sp, 0(t0)
|
||||
|
||||
STACK_GUARD_POST_SWITCH t3 0 _tee_stack_bottom _tee_stack
|
||||
|
||||
/* Set the privilege mode to transition to after mret to M-mode */
|
||||
li t0, MSTATUS_MPP
|
||||
csrs mstatus, t0
|
||||
@@ -504,17 +598,23 @@ _4:
|
||||
li t1, MSTATUS_MPP
|
||||
csrc mstatus, t1
|
||||
|
||||
/* Save the current secure stack pointer and switch to the U-mode interrupt stack
|
||||
* saved while entering the secure service call routine (see `_tee_s_entry`) */
|
||||
/* Save the current secure stack pointer */
|
||||
la t0, _s_sp
|
||||
sw sp, 0(t0)
|
||||
|
||||
STACK_GUARD_PRE_SWITCH t3 0
|
||||
|
||||
/* Switch to the saved U-mode stack */
|
||||
la t1, _ns_sp
|
||||
lw sp, 0(t1)
|
||||
fence
|
||||
|
||||
/* Set a flag to identify the next U2M switch would be after handling a U-mode interrupt */
|
||||
lui t0, RTNVAL
|
||||
csrw mscratch, t0
|
||||
|
||||
STACK_GUARD_POST_SWITCH t3 1 _ns_sp_min _ns_sp_max
|
||||
|
||||
/* Place magic bytes in all the general registers */
|
||||
store_magic_general_regs
|
||||
|
||||
@@ -577,8 +677,28 @@ _save_reg_ctx:
|
||||
_continue:
|
||||
/* Before doing anything preserve the stack pointer */
|
||||
mv s11, sp
|
||||
|
||||
/* NOTE: Cannot use the stack-guard macros here because they expect
|
||||
* static symbols, not register-based bounds. */
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* Check if stack monitoring is enabled */
|
||||
ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE t2 t3
|
||||
beqz t3, 1f
|
||||
|
||||
/* Save the REE stack guard bounds in s9/s10 (callee-saved registers) */
|
||||
ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE t2 s9 s10
|
||||
/* Stop the stack monitoring */
|
||||
ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE t0 t1
|
||||
fence
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* Switch to the TEE interrupt stack */
|
||||
la sp, _tee_intr_stack
|
||||
|
||||
STACK_GUARD_POST_SWITCH t3 0 _tee_intr_stack_bottom _tee_intr_stack
|
||||
fence
|
||||
|
||||
/* If this is a non-nested interrupt, SP now points to the interrupt stack */
|
||||
|
||||
/* Before dispatch c handler, restore interrupt to enable nested intr */
|
||||
@@ -623,9 +743,24 @@ _intr_hdlr_exec:
|
||||
csrw mcause, s1
|
||||
csrw mstatus, s2
|
||||
|
||||
STACK_GUARD_PRE_SWITCH t3 0
|
||||
|
||||
/* Restoring the stack pointer */
|
||||
mv sp, s11
|
||||
|
||||
/* NOTE: Cannot use the stack-guard macros here because they expect
|
||||
* static symbols, not register-based bounds. */
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* Check if stack monitoring was enabled (using saved state from t3) */
|
||||
beqz t3, 2f # Skip if monitoring was not enabled
|
||||
|
||||
/* Restore the REE stack bounds from s9/s10 (callee-saved registers) */
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE t2 s9 s10
|
||||
/* Resume stack monitoring */
|
||||
ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE t0 t1
|
||||
2:
|
||||
#endif
|
||||
|
||||
restore_mepc
|
||||
restore_general_regs RV_STK_FRMSZ
|
||||
/* exit, this will also re-enable the interrupts */
|
||||
@@ -635,7 +770,7 @@ _intr_hdlr_exec:
|
||||
|
||||
.section .text, "ax"
|
||||
|
||||
.align 4
|
||||
.balign 4
|
||||
.type _tee_s_entry, @function
|
||||
_tee_s_entry:
|
||||
/* Jump to the secure service dispatcher */
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#include "esp_tee_intr_defs.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
#include "esp_private/hw_stack_guard.h"
|
||||
#endif
|
||||
|
||||
.equ SAVE_REGS, 32
|
||||
.equ CONTEXT_SIZE, (SAVE_REGS * 4)
|
||||
.equ panic_from_exception, tee_panic_from_exc
|
||||
@@ -24,31 +28,112 @@
|
||||
.equ RTNVAL, 0xc0de
|
||||
.equ ECALL_U_MODE, 0x8
|
||||
.equ ECALL_M_MODE, 0xb
|
||||
/* NOTE: INTWDT timeout and Cache error interrupts trigger the panic
|
||||
* handler before reset, so they don’t need to be delegated. */
|
||||
.equ TEE_INTR_DELEG_MASK, ~((1U << TEE_SECURE_INUM) | (1U << ETS_INT_WDT_INUM) | (1U << ETS_CACHEERR_INUM))
|
||||
|
||||
/* NOTE: INTWDT timeout, Cache error and Stack protection interrupts
|
||||
* trigger the panic handler before reset, so they don't need to be delegated. */
|
||||
.equ TEE_INTR_DELEG_BASE, ((1U << TEE_SECURE_INUM) | (1U << ETS_INT_WDT_INUM) | (1U << ETS_CACHEERR_INUM))
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
.equ TEE_INTR_DELEG_MASK, ~(TEE_INTR_DELEG_BASE | (1U << ETS_ASSIST_DEBUG_INUM))
|
||||
#else
|
||||
.equ TEE_INTR_DELEG_MASK, ~(TEE_INTR_DELEG_BASE)
|
||||
#endif
|
||||
.global esp_tee_global_interrupt_handler
|
||||
.global esp_tee_service_dispatcher
|
||||
.global _tee_s_entry
|
||||
|
||||
.section .data
|
||||
.balign 4
|
||||
|
||||
.align 4
|
||||
.global _ns_sp
|
||||
_ns_sp:
|
||||
.word 0
|
||||
|
||||
.align 4
|
||||
.global _s_sp
|
||||
_s_sp:
|
||||
.word 0
|
||||
|
||||
.align 4
|
||||
.global _s_intr_thresh
|
||||
_s_intr_thresh:
|
||||
.word 0
|
||||
|
||||
.global _ns_sp_min
|
||||
_ns_sp_min:
|
||||
.word 0
|
||||
|
||||
.global _ns_sp_max
|
||||
_ns_sp_max:
|
||||
.word 0
|
||||
|
||||
/**
|
||||
* STACK_GUARD_PRE_SWITCH
|
||||
* Stops HW stack-guard monitoring and optionally saves current bounds.
|
||||
*
|
||||
* Args:
|
||||
* op_reg – output register for “monitoring enabled” state (must be reused)
|
||||
* to_save – 1=save bounds to memory, 0=skip saving
|
||||
* sp_min – symbol to store lower bound (if to_save=1)
|
||||
* sp_max – symbol to store upper bound (if to_save=1)
|
||||
*
|
||||
* Clobbers: t0, t1, t2, op_reg
|
||||
*/
|
||||
.macro STACK_GUARD_PRE_SWITCH op_reg, to_save, sp_min, sp_max
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* Query if monitoring is enabled: result goes into \op_reg */
|
||||
ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE t2 \op_reg
|
||||
beqz \op_reg, 1f
|
||||
|
||||
.if \to_save
|
||||
/* Save current REE/U-mode stack bounds */
|
||||
ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE t2 t0 t1
|
||||
la t2, \sp_min
|
||||
sw t0, 0(t2)
|
||||
la t2, \sp_max
|
||||
sw t1, 0(t2)
|
||||
.endif
|
||||
|
||||
/* Stop monitoring */
|
||||
ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE t0 t1
|
||||
fence
|
||||
1:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/**
|
||||
* STACK_GUARD_POST_SWITCH
|
||||
* Restores or applies new bounds after switching stacks, then restarts monitoring.
|
||||
*
|
||||
* Args:
|
||||
* op_reg – saved monitoring state from PRE_SWITCH
|
||||
* to_restore – 1=restore from memory, 0=set static bounds
|
||||
* sp_min – saved bound (restore) or static lower bound (S-mode)
|
||||
* sp_max – saved bound (restore) or static upper bound (S-mode)
|
||||
*
|
||||
* Clobbers: t0, t1, t2
|
||||
*/
|
||||
.macro STACK_GUARD_POST_SWITCH op_reg, to_restore, sp_min, sp_max
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* Check if monitoring was enabled (using saved state from op_reg) */
|
||||
beqz \op_reg, 1f
|
||||
|
||||
.if \to_restore
|
||||
/* Restore saved REE/U-mode bounds from memory */
|
||||
la t2, \sp_min
|
||||
lw t0, 0(t2)
|
||||
la t2, \sp_max
|
||||
lw t1, 0(t2)
|
||||
.else
|
||||
/* Use new TEE/S-mode stack bounds (static symbols) */
|
||||
la t0, \sp_min
|
||||
la t1, \sp_max
|
||||
.endif
|
||||
|
||||
/* Apply bounds to hardware stack guard */
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE t2 t0 t1
|
||||
/* Restart monitoring */
|
||||
ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE t0 t1
|
||||
1:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/* Macro which first allocates space on the stack to save general
|
||||
* purpose registers, and then save them. GP register is excluded.
|
||||
* The default size allocated on the stack is CONTEXT_SIZE, but it
|
||||
@@ -180,9 +265,10 @@ _s_intr_thresh:
|
||||
.section .exception_vectors.text, "ax"
|
||||
|
||||
/* Exception handler. */
|
||||
.global _tee_exception_handler
|
||||
.global _tee_panic_handler
|
||||
.type _tee_panic_handler, @function
|
||||
_tee_panic_handler:
|
||||
.type _tee_exception_handler, @function
|
||||
_tee_exception_handler:
|
||||
/* Backup t0, t1 on the stack before using it */
|
||||
addi sp, sp, -16
|
||||
sw t0, 0(sp)
|
||||
@@ -206,7 +292,7 @@ _tee_panic_handler:
|
||||
lw t1, 4(sp)
|
||||
addi sp, sp, 16
|
||||
|
||||
_actual_panic:
|
||||
_tee_panic_handler:
|
||||
/* Not an ecall, proceed to the panic handler */
|
||||
/* Allocate space on the stack and store general purpose registers */
|
||||
save_general_regs RV_STK_FRMSZ
|
||||
@@ -259,7 +345,7 @@ _return_from_exception:
|
||||
restore_general_regs RV_STK_FRMSZ
|
||||
mret
|
||||
|
||||
.size _tee_panic_handler, .-_tee_panic_handler
|
||||
.size _tee_exception_handler, .-_tee_exception_handler
|
||||
|
||||
/* ECALL handler. */
|
||||
.type _ecall_handler, @function
|
||||
@@ -289,9 +375,13 @@ _machine_ecall:
|
||||
sw t1, 0(t0)
|
||||
|
||||
_skip_thresh_restore:
|
||||
STACK_GUARD_PRE_SWITCH t3 0
|
||||
|
||||
/* Switching back to the saved REE stack */
|
||||
la t0, _ns_sp
|
||||
lw sp, 0(t0)
|
||||
|
||||
STACK_GUARD_POST_SWITCH t3 1 _ns_sp_min _ns_sp_max
|
||||
fence
|
||||
|
||||
/* Backup the A0 register
|
||||
@@ -344,13 +434,16 @@ _process_ecall:
|
||||
la t0, _ns_sp
|
||||
sw sp, 0(t0)
|
||||
|
||||
STACK_GUARD_PRE_SWITCH t3 1 _ns_sp_min _ns_sp_max
|
||||
|
||||
/* Switch to the M-mode (i.e. TEE) stack */
|
||||
la sp, _tee_stack
|
||||
|
||||
STACK_GUARD_POST_SWITCH t3 0 _tee_stack_bottom _tee_stack
|
||||
|
||||
/* Load the TEE entry point (see _tee_s_entry) in the mepc */
|
||||
la t0, _tee_s_entry
|
||||
csrw mepc, t0
|
||||
fence
|
||||
|
||||
/* Disable the U-mode delegation of all interrupts */
|
||||
csrwi mideleg, 0
|
||||
@@ -367,10 +460,14 @@ _rtn_from_ns_int:
|
||||
/* Disable the U-mode interrupt delegation */
|
||||
csrwi mideleg, 0
|
||||
|
||||
STACK_GUARD_PRE_SWITCH t3 0
|
||||
|
||||
/* Restore the secure stack pointer */
|
||||
la t0, _s_sp
|
||||
lw sp, 0(t0)
|
||||
|
||||
STACK_GUARD_POST_SWITCH t3 0 _tee_stack_bottom _tee_stack
|
||||
|
||||
/* Set the privilege mode to transition to after mret to M-mode */
|
||||
li t0, MSTATUS_MPP
|
||||
csrs mstatus, t0
|
||||
@@ -427,12 +524,16 @@ _tee_ns_intr_handler:
|
||||
li t1, MSTATUS_MPP
|
||||
csrc mstatus, t1
|
||||
|
||||
/* Save the current secure stack pointer and switch to the U-mode interrupt stack
|
||||
* saved while entering the secure service call routine (see `_tee_s_entry`) */
|
||||
/* Save the current secure stack pointer */
|
||||
la t0, _s_sp
|
||||
sw sp, 0(t0)
|
||||
|
||||
STACK_GUARD_PRE_SWITCH t3 0
|
||||
|
||||
/* Switch to the saved U-mode stack */
|
||||
la t1, _ns_sp
|
||||
lw sp, 0(t1)
|
||||
fence
|
||||
|
||||
/* Set a flag to identify the next U2M switch would be after handling a U-mode interrupt */
|
||||
lui t0, RTNVAL
|
||||
@@ -442,6 +543,8 @@ _tee_ns_intr_handler:
|
||||
li t0, TEE_INTR_DELEG_MASK
|
||||
csrs mideleg, t0
|
||||
|
||||
STACK_GUARD_POST_SWITCH t3 1 _ns_sp_min _ns_sp_max
|
||||
|
||||
/* Place magic bytes in all the general registers */
|
||||
store_magic_general_regs
|
||||
|
||||
@@ -506,8 +609,28 @@ _save_reg_ctx:
|
||||
_continue:
|
||||
/* Before doing anything preserve the stack pointer */
|
||||
mv s11, sp
|
||||
|
||||
/* NOTE: Cannot use the stack-guard macros here because they expect
|
||||
* static symbols, not register-based bounds. */
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* Check if stack monitoring is enabled */
|
||||
ESP_HW_STACK_GUARD_MONITOR_QUERY_CUR_CORE t2 t3
|
||||
beqz t3, 1f
|
||||
|
||||
/* Save the REE stack guard bounds in s9/s10 (callee-saved registers) */
|
||||
ESP_HW_STACK_GUARD_GET_BOUNDS_CUR_CORE t2 s9 s10
|
||||
/* Stop the stack monitoring */
|
||||
ESP_HW_STACK_GUARD_MONITOR_STOP_CUR_CORE t0 t1
|
||||
fence
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* Switch to the TEE interrupt stack */
|
||||
la sp, _tee_intr_stack
|
||||
|
||||
STACK_GUARD_POST_SWITCH t3 0 _tee_intr_stack_bottom _tee_intr_stack
|
||||
fence
|
||||
|
||||
/* If this is a non-nested interrupt, SP now points to the interrupt stack */
|
||||
|
||||
/* Before dispatch c handler, restore interrupt to enable nested intr */
|
||||
@@ -572,9 +695,24 @@ _intr_hdlr_exec:
|
||||
csrw mcause, s1
|
||||
csrw mstatus, s2
|
||||
|
||||
STACK_GUARD_PRE_SWITCH t3 0
|
||||
|
||||
/* Restoring the stack pointer */
|
||||
mv sp, s11
|
||||
|
||||
/* NOTE: Cannot use the stack-guard macros here because they expect
|
||||
* static symbols, not register-based bounds. */
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* Check if stack monitoring was enabled (using saved state from t3) */
|
||||
beqz t3, 2f # Skip if monitoring was not enabled
|
||||
|
||||
/* Restore the REE stack bounds from s9/s10 (callee-saved registers) */
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE t2 s9 s10
|
||||
/* Resume stack monitoring */
|
||||
ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE t0 t1
|
||||
2:
|
||||
#endif
|
||||
|
||||
restore_mepc
|
||||
restore_general_regs RV_STK_FRMSZ
|
||||
/* exit, this will also re-enable the interrupts */
|
||||
@@ -584,7 +722,7 @@ _intr_hdlr_exec:
|
||||
|
||||
.section .text, "ax"
|
||||
|
||||
.align 4
|
||||
.balign 4
|
||||
.type _tee_s_entry, @function
|
||||
_tee_s_entry:
|
||||
/* Jump to the secure service dispatcher */
|
||||
|
||||
@@ -154,6 +154,9 @@ void panic_print_isrcause(const void *f, int core)
|
||||
rsn = "Interrupt wdt timeout on CPU1";
|
||||
break;
|
||||
#endif
|
||||
case ETS_ASSIST_DEBUG_INUM:
|
||||
rsn = "Stack protection fault";
|
||||
break;
|
||||
}
|
||||
|
||||
panic_print_rsn(f, core, rsn);
|
||||
|
||||
@@ -70,7 +70,7 @@ void esp_tee_route_intr_matrix(int cpu_no, uint32_t model_num, uint32_t intr_num
|
||||
ESP_LOGV(TAG, "Connected src %d to int %d (cpu %d)", model_num, intr_num, cpu_no);
|
||||
|
||||
#if SOC_INT_CLIC_SUPPORTED
|
||||
if (intr_num != ETS_T1_WDT_INUM && intr_num != ETS_CACHEERR_INUM) {
|
||||
if (intr_num != ETS_T1_WDT_INUM && intr_num != ETS_CACHEERR_INUM && intr_num != ETS_ASSIST_DEBUG_INUM) {
|
||||
/* Configure interrupts to be visible in the TEE (M-mode) */
|
||||
REG_SET_BIT(DR_REG_INTMTX_BASE + 4 * model_num, BIT(8));
|
||||
/* Configure interrupts to be serviced in the REE (U-mode) */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Reducing TEE I/DRAM sizes
|
||||
# 28KB
|
||||
CONFIG_SECURE_TEE_IRAM_SIZE=0x7000
|
||||
# 29KB
|
||||
CONFIG_SECURE_TEE_IRAM_SIZE=0x7400
|
||||
|
||||
# TEE Secure Storage: Release mode
|
||||
CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y
|
||||
|
||||
@@ -69,3 +69,11 @@ secure_services:
|
||||
type: custom
|
||||
function: esp_tee_test_heap_malloc_write_free
|
||||
args: 0
|
||||
- id: 217
|
||||
type: custom
|
||||
function: esp_tee_test_stack_overflow
|
||||
args: 0
|
||||
- id: 218
|
||||
type: custom
|
||||
function: esp_tee_test_stack_underflow
|
||||
args: 0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -46,6 +46,45 @@ void _ss_esp_tee_test_iram_reg2_write_violation(void)
|
||||
*test_addr = RND_VAL;
|
||||
}
|
||||
|
||||
static void do_stack_smash(bool underflow, int depth, volatile uint8_t *sink)
|
||||
{
|
||||
/* Overflow path */
|
||||
if (!underflow) {
|
||||
if (depth == -1) {
|
||||
return; // unreachable
|
||||
}
|
||||
|
||||
uint8_t buffer[1024];
|
||||
buffer[0] = (uint8_t)depth;
|
||||
*sink = buffer[0];
|
||||
|
||||
do_stack_smash(false, depth + 1, sink);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Underflow path */
|
||||
asm volatile(
|
||||
"li t0, 2048\n"
|
||||
"add sp, sp, t0\n"
|
||||
);
|
||||
|
||||
volatile uint8_t a = 1;
|
||||
volatile uint8_t b = a;
|
||||
(void)b;
|
||||
}
|
||||
|
||||
void _ss_esp_tee_test_stack_overflow(void)
|
||||
{
|
||||
volatile uint8_t sink = 0;
|
||||
do_stack_smash(false, 1, &sink);
|
||||
}
|
||||
|
||||
void _ss_esp_tee_test_stack_underflow(void)
|
||||
{
|
||||
volatile uint8_t sink = 0;
|
||||
do_stack_smash(true, 0, &sink);
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
||||
static void foo_d(void)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#if SOC_AES_SUPPORTED
|
||||
#include "soc/aes_reg.h"
|
||||
@@ -21,6 +22,7 @@
|
||||
#include "soc/lp_wdt_reg.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
#include "soc/assist_debug_reg.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@@ -226,3 +228,55 @@ TEST_CASE("Test REE-TEE isolation: DROM-W1", "[exception]")
|
||||
*(uint32_t *)(test_addr - 0x04) = 0xbadc0de;
|
||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||
}
|
||||
|
||||
static void do_stack_smash(bool underflow, int depth, volatile uint8_t *sink)
|
||||
{
|
||||
/* Overflow path */
|
||||
if (!underflow) {
|
||||
if (depth == -1) {
|
||||
return; // unreachable
|
||||
}
|
||||
|
||||
uint8_t buffer[1024];
|
||||
buffer[0] = (uint8_t)depth;
|
||||
*sink = buffer[0];
|
||||
|
||||
do_stack_smash(false, depth + 1, sink);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Underflow path */
|
||||
asm volatile(
|
||||
"li t0, 4096\n"
|
||||
"add sp, sp, t0\n"
|
||||
);
|
||||
|
||||
volatile uint8_t temp = 1;
|
||||
(void)temp;
|
||||
}
|
||||
|
||||
TEST_CASE("Test REE stack overflow", "[exception]")
|
||||
{
|
||||
volatile uint8_t sink = 0;
|
||||
do_stack_smash(false, 1, &sink);
|
||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||
}
|
||||
|
||||
TEST_CASE("Test REE stack underflow", "[exception]")
|
||||
{
|
||||
volatile uint8_t sink = 0;
|
||||
do_stack_smash(true, 0, &sink);
|
||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||
}
|
||||
|
||||
TEST_CASE("Test TEE stack overflow", "[exception]")
|
||||
{
|
||||
esp_tee_service_call(1, SS_ESP_TEE_TEST_STACK_OVERFLOW);
|
||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||
}
|
||||
|
||||
TEST_CASE("Test TEE stack underflow", "[exception]")
|
||||
{
|
||||
esp_tee_service_call(1, SS_ESP_TEE_TEST_STACK_UNDERFLOW);
|
||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ TEE_VIOLATION_TEST_EXC_RSN: dict[str, str] = {
|
||||
('IRAM-W2'): 'Store access fault',
|
||||
('DRAM-X1'): 'Instruction access fault',
|
||||
('DRAM-X2'): 'Instruction access fault',
|
||||
('Illegal Instruction'): 'Illegal instruction',
|
||||
}
|
||||
|
||||
REE_ISOLATION_TEST_EXC_RSN: dict[str, str] = {
|
||||
@@ -128,19 +129,6 @@ def test_esp_tee_apm_violation(dut: IdfDut) -> None:
|
||||
raise RuntimeError('Incorrect exception received!')
|
||||
|
||||
|
||||
@idf_parametrize(
|
||||
'config, target, markers',
|
||||
CONFIG_DEFAULT,
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_esp_tee_illegal_instruction(dut: IdfDut) -> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.write('"Test TEE-TEE violation: Illegal Instruction"')
|
||||
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
|
||||
if exc != 'Illegal instruction':
|
||||
raise RuntimeError('Incorrect exception received!')
|
||||
|
||||
|
||||
@idf_parametrize(
|
||||
'config, target, markers',
|
||||
CONFIG_DEFAULT,
|
||||
@@ -183,6 +171,23 @@ def test_esp_tee_isolation_checks(dut: IdfDut) -> None:
|
||||
dut.expect('Origin: U-mode')
|
||||
|
||||
|
||||
@idf_parametrize(
|
||||
'config, target, markers',
|
||||
CONFIG_DEFAULT,
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_esp_tee_stack_smashing(dut: IdfDut) -> None:
|
||||
for env in ('REE', 'TEE'):
|
||||
for case in ('overflow', 'underflow'):
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.write(f'"Test {env} stack {case}"')
|
||||
|
||||
match = dut.expect(r"Core ([01]) panic'ed \(([^)]+)\)", timeout=30)
|
||||
exc = match.group(2).decode()
|
||||
if exc != 'Stack protection fault':
|
||||
raise RuntimeError('Incorrect exception received!')
|
||||
|
||||
|
||||
# ---------------- TEE Flash Protection Tests ----------------
|
||||
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ rtos_int_enter:
|
||||
/* esp_hw_stack_guard_set_bounds(xIsrStack, xIsrStackTop); */
|
||||
la a0, xIsrStack
|
||||
mv a1, sp
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 a0 a1
|
||||
/* esp_hw_stack_guard_monitor_start(); */
|
||||
ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE a0 a1
|
||||
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
|
||||
@@ -143,7 +143,7 @@ no_switch:
|
||||
*/
|
||||
lw a0, PORT_OFFSET_PX_STACK(t0)
|
||||
lw a1, PORT_OFFSET_PX_END_OF_STACK(t0)
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 a0 a1
|
||||
/* esp_hw_stack_guard_monitor_start(); */
|
||||
ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE a0 a1
|
||||
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
|
||||
|
||||
@@ -684,7 +684,7 @@ rtos_int_enter:
|
||||
mv a1, sp
|
||||
/* esp_hw_stack_guard_set_bounds(xIsrStackBottom[coreID], xIsrStackTop[coreID]);
|
||||
*/
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 a0 a1
|
||||
ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE a0 a1
|
||||
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
|
||||
|
||||
@@ -841,7 +841,7 @@ restore_stack_pointer:
|
||||
*/
|
||||
lw a1, PORT_OFFSET_PX_END_OF_STACK(a0)
|
||||
lw a0, PORT_OFFSET_PX_STACK(a0)
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CUR_CORE a2 a0 a1
|
||||
/* esp_hw_stack_guard_monitor_start(); */
|
||||
ESP_HW_STACK_GUARD_MONITOR_START_CUR_CORE a0 a1
|
||||
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
|
||||
|
||||
Reference in New Issue
Block a user