diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index 2bb4c1d44..9c3794c6b 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/ARMv8M/secure/context/secure_context.c +++ b/portable/ARMv8M/secure/context/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/GCC/ARM_CM23/secure/secure_context.c +++ b/portable/GCC/ARM_CM23/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/GCC/ARM_CM33/secure/secure_context.c +++ b/portable/GCC/ARM_CM33/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/GCC/ARM_CM35P/non_secure/port.c +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_context.c +++ b/portable/GCC/ARM_CM35P/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/GCC/ARM_CM52/non_secure/port.c +++ b/portable/GCC/ARM_CM52/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/GCC/ARM_CM52/secure/secure_context.c +++ b/portable/GCC/ARM_CM52/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/GCC/ARM_CM55/non_secure/port.c +++ b/portable/GCC/ARM_CM55/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/GCC/ARM_CM55/secure/secure_context.c +++ b/portable/GCC/ARM_CM55/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/GCC/ARM_CM85/non_secure/port.c +++ b/portable/GCC/ARM_CM85/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/GCC/ARM_CM85/secure/secure_context.c +++ b/portable/GCC/ARM_CM85/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/IAR/ARM_CM23/secure/secure_context.c +++ b/portable/IAR/ARM_CM23/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/IAR/ARM_CM33/secure/secure_context.c +++ b/portable/IAR/ARM_CM33/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/IAR/ARM_CM35P/non_secure/port.c +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_context.c +++ b/portable/IAR/ARM_CM35P/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/IAR/ARM_CM52/non_secure/port.c +++ b/portable/IAR/ARM_CM52/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/IAR/ARM_CM52/secure/secure_context.c +++ b/portable/IAR/ARM_CM52/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/IAR/ARM_CM55/non_secure/port.c +++ b/portable/IAR/ARM_CM55/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/IAR/ARM_CM55/secure/secure_context.c +++ b/portable/IAR/ARM_CM55/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 100644 --- a/portable/IAR/ARM_CM85/non_secure/port.c +++ b/portable/IAR/ARM_CM85/non_secure/port.c @@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 100644 --- a/portable/IAR/ARM_CM85/secure/secure_context.c +++ b/portable/IAR/ARM_CM85/secure/secure_context.c @@ -290,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 5e6ae3fe6..daf0d9458 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl 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 2bb4c1d44..9c3794c6b 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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #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 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO 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 ) )