Allow start scheduler and free context SVC from privileged code only (#1475)
Allow start scheduler and free context SVC from privileged code only
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/ARMv8M/non_secure/port.c
+++ b/portable/ARMv8M/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/ARMv8M/secure/context/secure_context.c b/portable/ARMv8M/secure/context/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/ARMv8M/secure/context/secure_context.c
+++ b/portable/ARMv8M/secure/context/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM23/non_secure/port.c
+++ b/portable/GCC/ARM_CM23/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_CM23/secure/secure_context.c b/portable/GCC/ARM_CM23/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/GCC/ARM_CM23/secure/secure_context.c
+++ b/portable/GCC/ARM_CM23/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c
+++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM33/non_secure/port.c
+++ b/portable/GCC/ARM_CM33/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_CM33/secure/secure_context.c b/portable/GCC/ARM_CM33/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/GCC/ARM_CM33/secure/secure_context.c
+++ b/portable/GCC/ARM_CM33/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c
+++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM35P/non_secure/port.c
+++ b/portable/GCC/ARM_CM35P/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_CM35P/secure/secure_context.c b/portable/GCC/ARM_CM35P/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/GCC/ARM_CM35P/secure/secure_context.c
+++ b/portable/GCC/ARM_CM35P/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c
+++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_CM52/non_secure/port.c b/portable/GCC/ARM_CM52/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM52/non_secure/port.c
+++ b/portable/GCC/ARM_CM52/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_CM52/secure/secure_context.c b/portable/GCC/ARM_CM52/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/GCC/ARM_CM52/secure/secure_context.c
+++ b/portable/GCC/ARM_CM52/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/GCC/ARM_CM52_NTZ/non_secure/port.c b/portable/GCC/ARM_CM52_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM52_NTZ/non_secure/port.c
+++ b/portable/GCC/ARM_CM52_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM55/non_secure/port.c
+++ b/portable/GCC/ARM_CM55/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_CM55/secure/secure_context.c b/portable/GCC/ARM_CM55/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/GCC/ARM_CM55/secure/secure_context.c
+++ b/portable/GCC/ARM_CM55/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c
+++ b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM85/non_secure/port.c
+++ b/portable/GCC/ARM_CM85/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_CM85/secure/secure_context.c b/portable/GCC/ARM_CM85/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/GCC/ARM_CM85/secure/secure_context.c
+++ b/portable/GCC/ARM_CM85/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c
+++ b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_STAR_MC3/non_secure/port.c b/portable/GCC/ARM_STAR_MC3/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_STAR_MC3/non_secure/port.c
+++ b/portable/GCC/ARM_STAR_MC3/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/GCC/ARM_STAR_MC3/secure/secure_context.c b/portable/GCC/ARM_STAR_MC3/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/GCC/ARM_STAR_MC3/secure/secure_context.c
+++ b/portable/GCC/ARM_STAR_MC3/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c b/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c
+++ b/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM23/non_secure/port.c
+++ b/portable/IAR/ARM_CM23/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM23/secure/secure_context.c b/portable/IAR/ARM_CM23/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/IAR/ARM_CM23/secure/secure_context.c
+++ b/portable/IAR/ARM_CM23/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c
+++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM33/non_secure/port.c
+++ b/portable/IAR/ARM_CM33/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM33/secure/secure_context.c b/portable/IAR/ARM_CM33/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/IAR/ARM_CM33/secure/secure_context.c
+++ b/portable/IAR/ARM_CM33/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c
+++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM35P/non_secure/port.c
+++ b/portable/IAR/ARM_CM35P/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM35P/secure/secure_context.c b/portable/IAR/ARM_CM35P/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/IAR/ARM_CM35P/secure/secure_context.c
+++ b/portable/IAR/ARM_CM35P/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c
+++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM52/non_secure/port.c b/portable/IAR/ARM_CM52/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM52/non_secure/port.c
+++ b/portable/IAR/ARM_CM52/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM52/secure/secure_context.c b/portable/IAR/ARM_CM52/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/IAR/ARM_CM52/secure/secure_context.c
+++ b/portable/IAR/ARM_CM52/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/IAR/ARM_CM52_NTZ/non_secure/port.c b/portable/IAR/ARM_CM52_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM52_NTZ/non_secure/port.c
+++ b/portable/IAR/ARM_CM52_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM55/non_secure/port.c
+++ b/portable/IAR/ARM_CM55/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM55/secure/secure_context.c b/portable/IAR/ARM_CM55/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/IAR/ARM_CM55/secure/secure_context.c
+++ b/portable/IAR/ARM_CM55/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c
+++ b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM85/non_secure/port.c
+++ b/portable/IAR/ARM_CM85/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_CM85/secure/secure_context.c b/portable/IAR/ARM_CM85/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/IAR/ARM_CM85/secure/secure_context.c
+++ b/portable/IAR/ARM_CM85/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c
+++ b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_STAR_MC3/non_secure/port.c b/portable/IAR/ARM_STAR_MC3/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_STAR_MC3/non_secure/port.c
+++ b/portable/IAR/ARM_STAR_MC3/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
diff --git a/portable/IAR/ARM_STAR_MC3/secure/secure_context.c b/portable/IAR/ARM_STAR_MC3/secure/secure_context.c
index 5e6ae3f..daf0d94 100644
--- a/portable/IAR/ARM_STAR_MC3/secure/secure_context.c
+++ b/portable/IAR/ARM_STAR_MC3/secure/secure_context.c
@@ -290,9 +290,12 @@
void * pvTaskHandle )
{
uint32_t ulIPSR, ulSecureContextIndex;
+ uint8_t * pucStackLimit;
- /* Read the Interrupt Program Status Register (IPSR) value. */
+ /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
+ * Register (PSPLIM) value. */
secureportREAD_IPSR( ulIPSR );
+ secureportREAD_PSPLIM( pucStackLimit );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
@@ -304,8 +307,14 @@
ulSecureContextIndex = xSecureContextHandle - 1UL;
/* Ensure that the secure context being deleted is associated with
- * the task. */
- if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
+ * the task and is NOT the currently-loaded context. Freeing a
+ * context whose stack is currently loaded in PSPLIM would leave the
+ * running task referencing freed secure memory (use-after-free).
+ * pvTaskHandle is supplied by the non-secure side and is untrusted,
+ * so it is used only as an additional ownership match, not as
+ * authority. */
+ if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
{
/* Free the stack space. */
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
diff --git a/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c b/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c
index 2bb4c1d..9c3794c 100644
--- a/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c
+++ b/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c
@@ -1109,7 +1109,6 @@
{
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if defined( __ARMCC_VERSION )
-
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@
#endif /* defined( __ARMCC_VERSION ) */
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
+ #if ( configENABLE_MPU == 1 )
+ #if defined( __ARMCC_VERSION )
+ /* Declaration when these variable are defined in code instead of being
+ * exported from linker scripts. */
+ extern uint32_t * __privileged_functions_start__;
+ extern uint32_t * __privileged_functions_end__;
+ #else
+ /* Declaration when these variable are exported from linker scripts. */
+ extern uint32_t __privileged_functions_start__[];
+ extern uint32_t __privileged_functions_end__[];
+ #endif /* defined( __ARMCC_VERSION ) */
+ #endif /* configENABLE_MPU == 1 */
+
uint32_t ulPC;
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@
break;
case portSVC_FREE_SECURE_CONTEXT:
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
+ {
+ #endif /* configENABLE_MPU */
+ /* R0 contains TCB being freed and R1 contains the secure
+ * context handle to be freed. */
+ ulR0 = pulCallerStackAddress[ 0 ];
+ ulR1 = pulCallerStackAddress[ 1 ];
- /* R0 contains TCB being freed and R1 contains the secure
- * context handle to be freed. */
- ulR0 = pulCallerStackAddress[ 0 ];
- ulR1 = pulCallerStackAddress[ 1 ];
-
- /* Free the secure context. */
- SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ /* Free the secure context. */
+ SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
+ #if ( configENABLE_MPU == 1 )
+ }
+ #endif /* configENABLE_MPU */
break;
#endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER:
- #if ( configENABLE_TRUSTZONE == 1 )
+ #if ( configENABLE_MPU == 1 )
+ if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
+ ( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
{
- /* De-prioritize the non-secure exceptions so that the
- * non-secure pendSV runs at the lowest priority. */
- SecureInit_DePrioritizeNSExceptions();
+ #endif /* configENABLE_MPU */
+ #if ( configENABLE_TRUSTZONE == 1 )
+ {
+ /* De-prioritize the non-secure exceptions so that the
+ * non-secure pendSV runs at the lowest priority. */
+ SecureInit_DePrioritizeNSExceptions();
- /* Initialize the secure context management system. */
- SecureContext_Init();
+ /* Initialize the secure context management system. */
+ SecureContext_Init();
+ }
+ #endif /* configENABLE_TRUSTZONE */
+
+ #if ( configENABLE_FPU == 1 )
+ {
+ /* Setup the Floating Point Unit (FPU). */
+ prvSetupFPU();
+ }
+ #endif /* configENABLE_FPU */
+
+ /* Setup the context of the first task so that the first task starts
+ * executing. */
+ vRestoreContextOfFirstTask();
+ #if ( configENABLE_MPU == 1 )
}
- #endif /* configENABLE_TRUSTZONE */
-
- #if ( configENABLE_FPU == 1 )
- {
- /* Setup the Floating Point Unit (FPU). */
- prvSetupFPU();
- }
- #endif /* configENABLE_FPU */
-
- /* Setup the context of the first task so that the first task starts
- * executing. */
- vRestoreContextOfFirstTask();
+ #endif /* configENABLE_MPU */
break;
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )