From 5f109e6f5546d6b328886a58aa0ec9fa96d87fe6 Mon Sep 17 00:00:00 2001 From: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com> Date: Fri, 21 Aug 2026 09:22:13 -0700 Subject: [PATCH 1/5] fix: Verify queue set type during usage (#1476) Verify that a queue set is passed when attempting to add a queue to the queue set. --- queue.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/queue.c b/queue.c index 83c7ac730..41ef8ef91 100644 --- a/queue.c +++ b/queue.c @@ -3225,7 +3225,16 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) taskENTER_CRITICAL(); { - if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) + if( ( ( Queue_t * ) xQueueSet )->uxItemSize != ( UBaseType_t ) sizeof( Queue_t * ) ) + { + /* The object passed as the queue set is not a queue set. A queue + * set always has an item size of sizeof( Queue_t * ). Reject any + * other object to prevent a type confusion in which + * prvNotifyQueueSetContainer() would later copy uxItemSize bytes + * from a single pointer on the stack. */ + xReturn = pdFAIL; + } + else if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) { /* Cannot add a queue/semaphore to more than one queue set. */ xReturn = pdFAIL; From ce36e042082b38c9ed684555e44ff0f87edab256 Mon Sep 17 00:00:00 2001 From: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com> Date: Fri, 21 Aug 2026 09:38:33 -0700 Subject: [PATCH 2/5] fix(armv8m): Reject undersized secure stack in AllocateContext (#1474) Gate against undersized stack values which do not account for fixed values. Thanks @aggarg for the help developing this! --- portable/ARMv8M/secure/context/secure_context.c | 6 +++++- portable/GCC/ARM_CM23/secure/secure_context.c | 6 +++++- portable/GCC/ARM_CM33/secure/secure_context.c | 6 +++++- portable/GCC/ARM_CM35P/secure/secure_context.c | 6 +++++- portable/GCC/ARM_CM52/secure/secure_context.c | 6 +++++- portable/GCC/ARM_CM55/secure/secure_context.c | 6 +++++- portable/GCC/ARM_CM85/secure/secure_context.c | 6 +++++- portable/GCC/ARM_STAR_MC3/secure/secure_context.c | 6 +++++- portable/IAR/ARM_CM23/secure/secure_context.c | 6 +++++- portable/IAR/ARM_CM33/secure/secure_context.c | 6 +++++- portable/IAR/ARM_CM35P/secure/secure_context.c | 6 +++++- portable/IAR/ARM_CM52/secure/secure_context.c | 6 +++++- portable/IAR/ARM_CM55/secure/secure_context.c | 6 +++++- portable/IAR/ARM_CM85/secure/secure_context.c | 6 +++++- portable/IAR/ARM_STAR_MC3/secure/secure_context.c | 6 +++++- 15 files changed, 75 insertions(+), 15 deletions(-) diff --git a/portable/ARMv8M/secure/context/secure_context.c b/portable/ARMv8M/secure/context/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/ARMv8M/secure/context/secure_context.c +++ b/portable/ARMv8M/secure/context/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/GCC/ARM_CM23/secure/secure_context.c b/portable/GCC/ARM_CM23/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/GCC/ARM_CM23/secure/secure_context.c +++ b/portable/GCC/ARM_CM23/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/GCC/ARM_CM33/secure/secure_context.c b/portable/GCC/ARM_CM33/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/GCC/ARM_CM33/secure/secure_context.c +++ b/portable/GCC/ARM_CM33/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/GCC/ARM_CM35P/secure/secure_context.c b/portable/GCC/ARM_CM35P/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_context.c +++ b/portable/GCC/ARM_CM35P/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/GCC/ARM_CM52/secure/secure_context.c b/portable/GCC/ARM_CM52/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/GCC/ARM_CM52/secure/secure_context.c +++ b/portable/GCC/ARM_CM52/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/GCC/ARM_CM55/secure/secure_context.c b/portable/GCC/ARM_CM55/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/GCC/ARM_CM55/secure/secure_context.c +++ b/portable/GCC/ARM_CM55/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/GCC/ARM_CM85/secure/secure_context.c b/portable/GCC/ARM_CM85/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/GCC/ARM_CM85/secure/secure_context.c +++ b/portable/GCC/ARM_CM85/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/GCC/ARM_STAR_MC3/secure/secure_context.c b/portable/GCC/ARM_STAR_MC3/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/GCC/ARM_STAR_MC3/secure/secure_context.c +++ b/portable/GCC/ARM_STAR_MC3/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/IAR/ARM_CM23/secure/secure_context.c b/portable/IAR/ARM_CM23/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/IAR/ARM_CM23/secure/secure_context.c +++ b/portable/IAR/ARM_CM23/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/IAR/ARM_CM33/secure/secure_context.c b/portable/IAR/ARM_CM33/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/IAR/ARM_CM33/secure/secure_context.c +++ b/portable/IAR/ARM_CM33/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/IAR/ARM_CM35P/secure/secure_context.c b/portable/IAR/ARM_CM35P/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_context.c +++ b/portable/IAR/ARM_CM35P/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/IAR/ARM_CM52/secure/secure_context.c b/portable/IAR/ARM_CM52/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/IAR/ARM_CM52/secure/secure_context.c +++ b/portable/IAR/ARM_CM52/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/IAR/ARM_CM55/secure/secure_context.c b/portable/IAR/ARM_CM55/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/IAR/ARM_CM55/secure/secure_context.c +++ b/portable/IAR/ARM_CM55/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/IAR/ARM_CM85/secure/secure_context.c b/portable/IAR/ARM_CM85/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/IAR/ARM_CM85/secure/secure_context.c +++ b/portable/IAR/ARM_CM85/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else diff --git a/portable/IAR/ARM_STAR_MC3/secure/secure_context.c b/portable/IAR/ARM_STAR_MC3/secure/secure_context.c index a7e13734d..5e6ae3fe6 100644 --- a/portable/IAR/ARM_STAR_MC3/secure/secure_context.c +++ b/portable/IAR/ARM_STAR_MC3/secure/secure_context.c @@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space if possible. */ - if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) + if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) || + ( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) ) { + /* Reject stacks that are too small (the CONTROL word would be + * written before the allocation, corrupting the secure heap) + * and sizes that would overflow when the seal size is added. */ pucStackMemory = NULL; } else From a0e2097c6a279dde2c92f3d63b19a73a17955b4f Mon Sep 17 00:00:00 2001 From: Anubhav Rawal Date: Fri, 21 Aug 2026 09:39:18 -0700 Subject: [PATCH 3/5] Validate timer command ID lower bound in xTimerGenericCommandFromTask (#1477) The task command path validated the command ID only against the upper bound. Add the corresponding lower-bound check so the accepted range is fully constrained. --- timers.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/timers.c b/timers.c index 1bc40bc46..b978f4298 100644 --- a/timers.c +++ b/timers.c @@ -467,9 +467,11 @@ xMessage.u.xTimerParameters.xMessageValue = xOptionalValue; xMessage.u.xTimerParameters.pxTimer = xTimer; - configASSERT( xCommandID < tmrFIRST_FROM_ISR_COMMAND ); + /* Enforce a lower bound as well as an upper bound so that only + * valid task-issued commands are accepted here. */ + configASSERT( ( xCommandID >= tmrCOMMAND_START_DONT_TRACE ) && ( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) ); - if( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) + if( ( xCommandID >= tmrCOMMAND_START_DONT_TRACE ) && ( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) ) { if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) { From 3ca84562d8431b0d71fe975ea1d30a0f11e3b25b Mon Sep 17 00:00:00 2001 From: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com> Date: Fri, 21 Aug 2026 10:24:35 -0700 Subject: [PATCH 4/5] Allow start scheduler and free context SVC from privileged code only (#1475) Allow start scheduler and free context SVC from privileged code only Signed-off-by: Gaurav Aggarwal --- portable/ARMv8M/non_secure/port.c | 79 +++++++++++++------ .../ARMv8M/secure/context/secure_context.c | 15 +++- portable/GCC/ARM_CM23/non_secure/port.c | 79 +++++++++++++------ portable/GCC/ARM_CM23/secure/secure_context.c | 15 +++- portable/GCC/ARM_CM23_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/GCC/ARM_CM33/non_secure/port.c | 79 +++++++++++++------ portable/GCC/ARM_CM33/secure/secure_context.c | 15 +++- portable/GCC/ARM_CM33_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/GCC/ARM_CM35P/non_secure/port.c | 79 +++++++++++++------ .../GCC/ARM_CM35P/secure/secure_context.c | 15 +++- portable/GCC/ARM_CM35P_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/GCC/ARM_CM52/non_secure/port.c | 79 +++++++++++++------ portable/GCC/ARM_CM52/secure/secure_context.c | 15 +++- portable/GCC/ARM_CM52_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/GCC/ARM_CM55/non_secure/port.c | 79 +++++++++++++------ portable/GCC/ARM_CM55/secure/secure_context.c | 15 +++- portable/GCC/ARM_CM55_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/GCC/ARM_CM85/non_secure/port.c | 79 +++++++++++++------ portable/GCC/ARM_CM85/secure/secure_context.c | 15 +++- portable/GCC/ARM_CM85_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/GCC/ARM_STAR_MC3/non_secure/port.c | 79 +++++++++++++------ .../GCC/ARM_STAR_MC3/secure/secure_context.c | 15 +++- .../GCC/ARM_STAR_MC3_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_CM23/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_CM23/secure/secure_context.c | 15 +++- portable/IAR/ARM_CM23_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_CM33/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_CM33/secure/secure_context.c | 15 +++- portable/IAR/ARM_CM33_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_CM35P/non_secure/port.c | 79 +++++++++++++------ .../IAR/ARM_CM35P/secure/secure_context.c | 15 +++- portable/IAR/ARM_CM35P_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_CM52/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_CM52/secure/secure_context.c | 15 +++- portable/IAR/ARM_CM52_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_CM55/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_CM55/secure/secure_context.c | 15 +++- portable/IAR/ARM_CM55_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_CM85/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_CM85/secure/secure_context.c | 15 +++- portable/IAR/ARM_CM85_NTZ/non_secure/port.c | 79 +++++++++++++------ portable/IAR/ARM_STAR_MC3/non_secure/port.c | 79 +++++++++++++------ .../IAR/ARM_STAR_MC3/secure/secure_context.c | 15 +++- .../IAR/ARM_STAR_MC3_NTZ/non_secure/port.c | 79 +++++++++++++------ 44 files changed, 1717 insertions(+), 799 deletions(-) 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 ) ) From 92bfb86ce3a3f5d0255e5b2e51636e5a5732b66a Mon Sep 17 00:00:00 2001 From: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com> Date: Fri, 21 Aug 2026 10:31:19 -0700 Subject: [PATCH 5/5] Add V11.3.1 changelog entry (#1478) --- History.txt | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/History.txt b/History.txt index c9b18cb44..7baa62ab7 100644 --- a/History.txt +++ b/History.txt @@ -1,5 +1,140 @@ Documentation and download available at https://www.FreeRTOS.org/ +Changes between FreeRTOS V11.3.0 and FreeRTOS V11.3.1 released August 2026 + + + Add Symmetric Multiprocessing (SMP) support to the Armv8-M ports for the + GCC, ArmClang and IAR toolchains. This adds per core critical nesting + state, spinlocks, inter-core yield and wakeup using SEV/WFE, primary and + secondary core bring up synchronization, and a core safe PendSV context + switch. Single core builds are unchanged. We thank @AhmedIsmail02 for + their contribution. + + Add new xTaskPeriodicDelay API for periodic tasks. It supersedes + xTaskDelayUntil by preventing run away of pxPreviousWakeTime, catching up + skipped periods immediately while returning the number of periods skipped, + and returning 0 when not enough ticks have elapsed. We thank @ntd for + their contribution. + + Add uxTaskCallForEachTask API, which invokes a caller supplied callback + for each task in the system, and refactor uxTaskGetSystemState to use it. + We thank @DRNadler for their contribution. + + Add configIDLE_AFFINITY configuration option, which pins each Idle task to + its corresponding core in SMP systems. It defaults to 0, which allows the + scheduler to run Idle tasks on any available core. We thank @rus084 for + their contribution. + + Add validation to SecureContext_AllocateContext in the ARMv8-M secure side + ports to ensure that the requested secure stack size plus the stack seal + size does not overflow before allocating. We thank Jordan Mecom (Block, + Inc.) for reporting this issue. + + Add assertions to vQueueDelete to check that no tasks are blocked on the + queue being deleted. + + Add a link to the FreeRTOS Kernel threat model in SECURITY.md. + + Add documentation clarifying that the MemoryRegion_t ulParameters macros + are port specific, so applications must use the tskMPU_REGION_* or + portMPU_REGION_* values that match their MPU port. We thank @Old-Ding for + their contribution. + + Add a comment documenting that a privileged task must revoke access + permissions before deleting a kernel object when using Access Control + Lists. + + Update the ARM_CRx_No_GIC port to declare vPortYield as a weak symbol so + that devices with a dedicated software interrupt register can substitute + their own yield trigger. The default behavior is unchanged. We thank + @maximdeclercq for their contribution. + + Update the FreeRTOSConfig.h template to use a 32-bit tick type, which + avoids compiler warnings on Windows where a 64-bit tick resolves to + unsigned long long. + + Update the deprecated CMake configuration warning to use INTERFACE rather + than PUBLIC for the freertos_config interface library. We thank @Isla-jq + for their contribution. + + Fix vPortFreeSecureContext in the ARMv8-M ports to read xSecureContext at + the correct offset. When the MPU is enabled, the first item in the TCB is + the stored context location rather than the top of stack, so + xSecureContext is located at a negative offset from that position. + + Fix SecureContext_AllocateContext in the ARMv8-M secure side ports to + reject a secure stack size smaller than the stack seal size. + + Fix SecureContext_FreeContext in the ARMv8-M secure side ports to refuse + to free the secure context that is currently loaded, as indicated by + PSPLIM. Freeing it left the running task referencing freed secure memory. + The task handle supplied by the non-secure side is untrusted, so it is + now used only as an additional ownership check. + + Fix the ARMv8-M ports to service the portSVC_START_SCHEDULER and + portSVC_FREE_SECURE_CONTEXT supervisor calls only when they are raised + from privileged code. When the MPU is enabled, both requests are now + ignored unless the calling program counter lies within the privileged + functions section. + + Fix a type confusion in xQueueAddToSet by verifying that the object + passed as the queue set really is a queue set, that is, that its item + size is sizeof( Queue_t * ). Passing an ordinary queue now returns + pdFAIL rather than allowing prvNotifyQueueSetContainer to copy item size + bytes from a single pointer on the stack. + + Fix xTimerGenericCommandFromTask to validate the lower bound of + xCommandID in addition to the existing upper bound, so that only the + valid task command range from tmrCOMMAND_START_DONT_TRACE to + tmrCOMMAND_DELETE is accepted. Rejected commands return pdFAIL, and + behavior for valid commands and for xTimerGenericCommandFromISR is + unchanged. + + Fix a kernel object pool entry leak by adding an MPU wrapper for the + xTimerDelete API, so that the pool index is freed when a timer is deleted + with MPU wrappers version 2. + + Fix the MPU wrapper macro mapping for the ARMv8-M ports. + + Fix silently failing critical sections in unprivileged tasks by + disallowing configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS with MPU wrappers + version 2 in the ARMv7-M MPU ports. The option now defaults to 0 under + version 2, and explicitly setting it to 1 raises a compile time error. + Behavior with MPU wrappers version 1 is unchanged. + + Fix a time of check to time of use race condition in vTaskListTasks, where + reading the volatile task count twice allowed a task to be created between + the reads, resulting in an undersized allocation and a possible buffer + overflow in uxTaskGetSystemState. We thank @srpatcha for their + contribution. + + Fix a spurious heap_5 assertion when configENABLE_HEAP_PROTECTOR is 1 and + an allocation cannot be satisfied. The free block search reaching the end + marker is a normal out of memory condition, so pvPortMalloc now returns + NULL and invokes the malloc failed hook instead of asserting. + + Fix batching stream buffers to unblock a receiver only after the buffered + byte count exceeds, rather than reaches, the trigger level. Previously a + receiver could be woken early and xStreamBufferReceive could return 0 + bytes. Stream buffer and message buffer semantics are unchanged. We thank + @officialasishkumar for their contribution. + + Fix MISRA C 2012 Rule 20.4 violation by replacing `#define static` with a + STATIC macro, which also keeps the static variables in + vApplicationGetIdleTaskMemory and vApplicationGetPassiveIdleTaskMemory + static when portREMOVE_STATIC_QUALIFIER is defined. We thank @elsonwei for + their contribution. + + Fix undefined behavior in the MSVC-MingW port caused by left shifting a + signed int by 31 or more bits. + + Fix a duplicate Doxygen \defgroup identifier by giving + uxTaskBasePriorityGet its own group instead of reusing the + uxTaskPriorityGet group. + + Fix the incorrect #endif comment after vPortSetupTimerInterrupt in the GCC + and IAR RISC-V ports, which duplicated configMTIME_BASE_ADDRESS and + omitted configMTIMECMP_BASE_ADDRESS. We thank @cuiweixie for their + contribution. + + Fix incorrect #endif comments in croutine.c and queue.c, which reversed + the configUSE_CO_ROUTINES condition and named the wrong configuration + option for configSUPPORT_DYNAMIC_ALLOCATION. We thank @Zepp-Hanzj for + their contribution. + + Fix the configLIST_VOLATILE #endif comment and the documented parameter + names for uxListRemove in include/list.h. We thank @rakeshr-source for + their contribution. + + Fix the type and timeout values used in the xStreamBufferSend and + xMessageBufferSend documentation examples. We thank @Isla-jq for their + contribution. + + Fix copy and paste comment typos in xTaskGetApplicationTaskTag and + xTaskGetApplicationTaskTagFromISR, and a typo in the + xTaskGenericNotifyWait comment. We thank @wanghengZzz for their + contributions. + + Fix comment typos in the queue.h, list.h and task.h documentation, + including the xQueueReceiveFromISR and xQueueGenericSend examples, the + listGET_ITEM_VALUE_OF_HEAD_ENTRY \page tag, and the uxIndexToCLear typo. + We thank @zepp-chen for their contribution. + + Fix the FreeRTOSConfig.h template path referenced in README.md. We thank + @IClementI for their contribution. + + Fix the missing V prefix in the release_tag and namespace-prefix inputs of + the auto release workflow. + + Fix long path failures in the Windows kernel demo builds by enabling + Windows long path support in CI. + + Remove an unnecessary const variable from the GCC and IAR RISC-V ports. We + thank @IClementI for their contribution. + Changes between FreeRTOS V11.2.0 and FreeRTOS V11.3.0 released March 2026 + Correct minor mistakes in code comments in event_groups.c, include/queue.h,