From b178814998ceb08c007af5b009623de73835af9f Mon Sep 17 00:00:00 2001 From: Nicola Fontana Date: Mon, 3 Aug 2026 17:04:06 +0200 Subject: [PATCH 01/10] New API xTaskPeriodicDelay (#1349) (#1368) * New API xTaskPeriodicDelay (#1349) New function to be used for periodic tasks to ensure a constant execution frequency. It is intended to supersede xTaskDelayUntil to overcome its shortcomings, that is: - avoid run away of pxPreviousWakeTime (#1339) - catch up any skipped period immediately (and update pxPreviousWakeTime accordingly), notify the caller of the number of periods skipped (by returning them) and wait until the next period (it could be less than xTimeIncrement if we are close to the next period) - notify the caller when not enough ticks have been elapsed (by returning 0) and handle the situation gracefully (by properly waiting until the next wake time) Signed-off-by: Nicola Fontana Co-authored-by: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com> --- include/FreeRTOS.h | 8 ++++++++ include/task.h | 37 ++++++++++++++++++++++++++++++++++ tasks.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 83fd430bd..f5411fdd6 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -1770,6 +1770,14 @@ #define traceRETURN_vTaskDelete() #endif +#ifndef traceENTER_xTaskPeriodicDelay + #define traceENTER_xTaskPeriodicDelay( pxPreviousWakeTime, xTimeIncrement ) +#endif + +#ifndef traceRETURN_xTaskPeriodicDelay + #define traceRETURN_xTaskPeriodicDelay( xIncrements ) +#endif + #ifndef traceENTER_xTaskDelayUntil #define traceENTER_xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ) #endif diff --git a/include/task.h b/include/task.h index 679b6fcea..c650b6497 100644 --- a/include/task.h +++ b/include/task.h @@ -893,6 +893,43 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; */ void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; +/** + * task. h + * @code{c} + * TickType_t xTaskPeriodicDelay( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement ); + * @endcode + * + * INCLUDE_xTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Periodic task delay to ensure a constant execution frequency. + * + * This function is similar to xTaskDelayUntil () with a few important differences: + * - pxPreviousWakeTime contains the last past wake time, so it never runs away + * - if you suspend the task, when you resume it pxPreviousWakeTime will instantly + * catch up all skipped increments + * - it returns the number of increments added to pxPreviosWakeTime + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use. Following this the variable is automatically updated. + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Passing the same xTimeIncrement + * parameter value will cause the task to execute with a fixed interval. + * + * @return Number of times xTimeIncrement has been added to pxPreviousWakeTime. + * It is 0 on the first call or if not enough ticks have been elapsed since the + * last call, 1 in normal circumstances or more than 1 if some period has been + * skipped for some reason (e.g. when the caller task is suspended for more than + * xTimeIncrement ticks). + * + * \defgroup xTaskPeriodicDelay xTaskPeriodicDelay + * \ingroup TaskCtrl + */ +TickType_t xTaskPeriodicDelay( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; + /** * task. h * @code{c} diff --git a/tasks.c b/tasks.c index e11712927..4c308daf7 100644 --- a/tasks.c +++ b/tasks.c @@ -2362,6 +2362,55 @@ STATIC void prvInitialiseNewTask( TaskFunction_t pxTaskCode, #if ( INCLUDE_xTaskDelayUntil == 1 ) + TickType_t xTaskPeriodicDelay( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) + { + TickType_t xIncrements, xTicksIncrements, xTicksToWait; + + traceENTER_xTaskPeriodicDelay( pxPreviousWakeTime, xTimeIncrement ); + + configASSERT( pxPreviousWakeTime ); + configASSERT( ( xTimeIncrement > 0U ) ); + + vTaskSuspendAll(); + { + /* As long as everything is the same type, this plays well with overflows */ + const TickType_t xTicksElapsed = xTickCount - *pxPreviousWakeTime; + + configASSERT( uxSchedulerSuspended == 1U ); + + /* Number of increments to catch up: it could be 0 if + * not enough ticks have elapsed, 1 in the common case or + * more than 1 if the task has not been resumed in time */ + xIncrements = xTicksElapsed / xTimeIncrement; + xTicksIncrements = xIncrements * xTimeIncrement; + + /* Update to the last wake time */ + *pxPreviousWakeTime += xTicksIncrements; + + /* Ticks to the next wake time */ + xTicksToWait = xTimeIncrement - ( xTicksElapsed - xTicksIncrements ); + + prvAddCurrentTaskToDelayedList( xTicksToWait, pdFALSE ); + } + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + * have put ourselves to sleep. */ + if( xTaskResumeAll() == pdFALSE ) + { + taskYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceRETURN_xTaskPeriodicDelay( xIncrements ); + + return xIncrements; + } + + BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) { From c5d22b28f2f5750795b2e9c711659f8889683375 Mon Sep 17 00:00:00 2001 From: wanghengZzz <150767771+wanghengZzz@users.noreply.github.com> Date: Sat, 8 Aug 2026 01:49:32 +0800 Subject: [PATCH 02/10] docs(tasks): fix typo in xTaskGenericNotifyWait comment (#1455) --- tasks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks.c b/tasks.c index 4c308daf7..76f6e5db9 100644 --- a/tasks.c +++ b/tasks.c @@ -7979,7 +7979,7 @@ TickType_t uxTaskResetEventItemValue( void ) *pulNotificationValue = pxCurrentTCB->ulNotifiedValue[ uxIndexToWaitOn ]; } - /* If ucNotifyValue is set then either the task never entered the + /* If ucNotifyState is set then either the task never entered the * blocked state (because a notification was already pending) or the * task unblocked because of a notification. Otherwise the task * unblocked because of a timeout. */ From ce221a8bb468e462ca6b435cef66a9636e00baf4 Mon Sep 17 00:00:00 2001 From: zepp-chen Date: Sat, 8 Aug 2026 07:14:30 +0800 Subject: [PATCH 03/10] Fix comment typos (#1461) Fix several documentation and example-code issues in the kernel header comments: * queue.h: remove a stray semicolon after the 'if' and correct the xHigherPriorityTaskWoken variable casing in the xQueueReceiveFromISR() example; add the missing comma between parameters in the xQueueGenericSend() prototype example. * list.h: correct the doxygen \page tag for listGET_ITEM_VALUE_OF_HEAD_ENTRY. * task.h: fix the uxIndexToCLear typo (-> uxIndexToClear). These are documentation/example only changes that do not affect the compiled library. Signed-off-by: chenrongjun --- .../template_configuration/FreeRTOSConfig.h | 2 +- include/croutine.h | 4 ++-- include/list.h | 8 +++---- include/queue.h | 22 +++++++++---------- include/task.h | 12 +++++----- .../portable/GCC/ARM_CM23/portasm.c | 8 +++---- .../portable/GCC/ARM_CM23_NTZ/portasm.c | 8 +++---- .../ARMv8M/secure/context/secure_context.c | 2 +- portable/CodeWarrior/HCS12/port.c | 2 +- portable/GCC/ARM_CM0/port.c | 2 +- portable/GCC/ARM_CM0/portasm.c | 8 +++---- portable/GCC/ARM_CM23/non_secure/portasm.c | 8 +++---- portable/GCC/ARM_CM23/secure/secure_context.c | 2 +- .../GCC/ARM_CM23_NTZ/non_secure/portasm.c | 8 +++---- portable/GCC/ARM_CM33/secure/secure_context.c | 2 +- .../GCC/ARM_CM35P/secure/secure_context.c | 2 +- portable/GCC/ARM_CM3_MPU/port.c | 2 +- portable/GCC/ARM_CM4_MPU/port.c | 2 +- portable/GCC/ARM_CM52/secure/secure_context.c | 2 +- portable/GCC/ARM_CM55/secure/secure_context.c | 2 +- portable/GCC/ARM_CM85/secure/secure_context.c | 2 +- portable/GCC/ARM_CRx_MPU/port.c | 2 +- .../GCC/ARM_STAR_MC3/secure/secure_context.c | 2 +- portable/GCC/HCS12/port.c | 2 +- portable/GCC/MicroBlaze/port.c | 4 ++-- portable/GCC/MicroBlazeV8/portmacro.h | 2 +- portable/GCC/MicroBlazeV9/portmacro.h | 2 +- ...freertos_risc_v_chip_specific_extensions.h | 2 +- ...freertos_risc_v_chip_specific_extensions.h | 2 +- ...freertos_risc_v_chip_specific_extensions.h | 2 +- ...freertos_risc_v_chip_specific_extensions.h | 2 +- portable/IAR/ARM_CM23/secure/secure_context.c | 2 +- portable/IAR/ARM_CM33/secure/secure_context.c | 2 +- .../IAR/ARM_CM35P/secure/secure_context.c | 2 +- portable/IAR/ARM_CM4F_MPU/port.c | 2 +- portable/IAR/ARM_CM52/secure/secure_context.c | 2 +- portable/IAR/ARM_CM55/secure/secure_context.c | 2 +- portable/IAR/ARM_CM85/secure/secure_context.c | 2 +- .../IAR/ARM_STAR_MC3/secure/secure_context.c | 2 +- ...freertos_risc_v_chip_specific_extensions.h | 2 +- portable/MPLAB/PIC32MEC14xx/ISR_Support.h | 2 +- portable/MPLAB/PIC32MX/ISR_Support.h | 2 +- portable/MPLAB/PIC32MZ/ISR_Support.h | 2 +- portable/RVDS/ARM_CM4_MPU/port.c | 2 +- stream_buffer.c | 4 ++-- tasks.c | 4 ++-- 46 files changed, 83 insertions(+), 83 deletions(-) diff --git a/examples/template_configuration/FreeRTOSConfig.h b/examples/template_configuration/FreeRTOSConfig.h index 4a74fe4ca..58727854d 100644 --- a/examples/template_configuration/FreeRTOSConfig.h +++ b/examples/template_configuration/FreeRTOSConfig.h @@ -577,7 +577,7 @@ /* Defines the kernel provided implementation of * vApplicationGetIdleTaskMemory() and vApplicationGetTimerTaskMemory() * to provide the memory that is used by the Idle task and Timer task - * respectively. The application can provide it's own implementation of + * respectively. The application can provide its own implementation of * vApplicationGetIdleTaskMemory() and vApplicationGetTimerTaskMemory() by * setting configKERNEL_PROVIDED_STATIC_MEMORY to 0 or leaving it undefined. */ #define configKERNEL_PROVIDED_STATIC_MEMORY 1 diff --git a/include/croutine.h b/include/croutine.h index a5e2e4462..616553669 100644 --- a/include/croutine.h +++ b/include/croutine.h @@ -528,7 +528,7 @@ void vCoRoutineSchedule( void ); * functions used by tasks. * * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to - * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * pass data between a co-routine and ISR, whereas xQueueSendFromISR() and * xQueueReceiveFromISR() can only be used to pass data between a task and and * ISR. * @@ -628,7 +628,7 @@ void vCoRoutineSchedule( void ); * functions used by tasks. * * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to - * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * pass data between a co-routine and ISR, whereas xQueueSendFromISR() and * xQueueReceiveFromISR() can only be used to pass data between a task and and * ISR. * diff --git a/include/list.h b/include/list.h index f9a8c00f6..1c0232369 100644 --- a/include/list.h +++ b/include/list.h @@ -31,7 +31,7 @@ * heavily for the schedulers needs, it is also available for use by * application code. * - * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a + * List_t can only store pointers to ListItem_t. Each ListItem_t contains a * numeric value (xItemValue). Most of the time the lists are sorted in * ascending item value order. * @@ -42,7 +42,7 @@ * is because the tail contains a wrap back pointer to the true head of * the list. * - * In addition to it's value, each list item contains a pointer to the next + * In addition to its value, each list item contains a pointer to the next * item in the list (pxNext), a pointer to the list it is in (pxContainer) * and a pointer back to the object that contains it. These later two * pointers are included for efficiency of list manipulation. There is @@ -74,7 +74,7 @@ * compiler's options were set for maximum optimisation has been inspected and * deemed to be as intended. That said, as compiler technology advances, and * especially if aggressive cross module optimisation is used (a use case that - * has not been exercised to any great extend) then it is feasible that the + * has not been exercised to any great extent) then it is feasible that the * volatile qualifier will be needed for correct optimisation. It is expected * that a compiler removing essential code because, without the volatile * qualifier on the list structure members and with aggressive cross module @@ -219,7 +219,7 @@ typedef struct xLIST * Access macro to retrieve the value of the list item at the head of a given * list. * - * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \page listGET_ITEM_VALUE_OF_HEAD_ENTRY listGET_ITEM_VALUE_OF_HEAD_ENTRY * \ingroup LinkedList */ #define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) diff --git a/include/queue.h b/include/queue.h index e3dbbefd2..90d185c3d 100644 --- a/include/queue.h +++ b/include/queue.h @@ -44,7 +44,7 @@ /** * Type by which queues are referenced. For example, a call to xQueueCreate() - * returns an QueueHandle_t variable that can then be used as a parameter to + * returns a QueueHandle_t variable that can then be used as a parameter to * xQueueSend(), xQueueReceive(), etc. */ struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */ @@ -60,7 +60,7 @@ typedef struct QueueDefinition * QueueSetHandle_t; /** * Queue sets can contain both queues and semaphores, so the * QueueSetMemberHandle_t is defined as a type to be used where a parameter or - * return value can be either an QueueHandle_t or an SemaphoreHandle_t. + * return value can be either a QueueHandle_t or a SemaphoreHandle_t. */ typedef struct QueueDefinition * QueueSetMemberHandle_t; @@ -185,7 +185,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * @param pucQueueStorage If uxItemSize is not zero then * pucQueueStorage must point to a uint8_t array that is at least large * enough to hold the maximum number of items that can be in the queue at any - * one time - which is ( uxQueueLength * uxItemsSize ) bytes. If uxItemSize is + * one time - which is ( uxQueueLength * uxItemSize ) bytes. If uxItemSize is * zero then pucQueueStorage can be NULL. * * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which @@ -604,7 +604,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; * BaseType_t xQueueGenericSend( * QueueHandle_t xQueue, * const void * pvItemToQueue, - * TickType_t xTicksToWait + * TickType_t xTicksToWait, * BaseType_t xCopyPosition * ); * @endcode @@ -1189,7 +1189,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; * * // ... * - * if( xHigherPrioritytaskWoken == pdTRUE ) + * if( xHigherPriorityTaskWoken == pdTRUE ) * { * // Writing to the queue caused a task to unblock and the unblocked task * // has a priority higher than or equal to the priority of the currently @@ -1451,7 +1451,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, * // task will be woken. * } * - * if( xHigherPrioritytaskWoken == pdTRUE ); + * if( xHigherPriorityTaskWoken == pdTRUE ) * { * // As xHigherPriorityTaskWoken is now set to pdTRUE then a context * // switch should be requested. The macro used is port specific and @@ -1664,7 +1664,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; * Note 2: Blocking on a queue set that contains a mutex will not cause the * mutex holder to inherit the priority of the blocked task. * - * Note 3: An additional 4 bytes of RAM is required for each space in a every + * Note 3: An additional 4 bytes of RAM is required for each space in every * queue added to a queue set. Therefore counting semaphores that have a high * maximum count value should not be added to a queue set. * @@ -1716,7 +1716,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; * Note 2: Blocking on a queue set that contains a mutex will not cause the * mutex holder to inherit the priority of the blocked task. * - * Note 3: An additional 4 bytes of RAM is required for each space in a every + * Note 3: An additional 4 bytes of RAM is required for each space in every * queue added to a queue set. Therefore counting semaphores that have a high * maximum count value should not be added to a queue set. * @@ -1767,7 +1767,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; * a call to xQueueSelectFromSet() has first returned a handle to that set member. * * @param xQueueOrSemaphore The handle of the queue or semaphore being added to - * the queue set (cast to an QueueSetMemberHandle_t type). + * the queue set (cast to a QueueSetMemberHandle_t type). * * @param xQueueSet The handle of the queue set to which the queue or semaphore * is being added. @@ -1790,7 +1790,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; * function. * * @param xQueueOrSemaphore The handle of the queue or semaphore being removed - * from the queue set (cast to an QueueSetMemberHandle_t type). + * from the queue set (cast to a QueueSetMemberHandle_t type). * * @param xQueueSet The handle of the queue set in which the queue or semaphore * is included. @@ -1836,7 +1836,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; * a QueueSetMemberHandle_t type) contained in the queue set that contains data, * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained * in the queue set that is available, or NULL if no such queue or semaphore - * exists before before the specified block time expires. + * exists before the specified block time expires. */ #if ( configUSE_QUEUE_SETS == 1 ) QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, diff --git a/include/task.h b/include/task.h index c650b6497..193d242f5 100644 --- a/include/task.h +++ b/include/task.h @@ -89,7 +89,7 @@ * task. h * * Type by which tasks are referenced. For example, a call to xTaskCreate - * returns (via a pointer parameter) an TaskHandle_t variable that can then + * returns (via a pointer parameter) a TaskHandle_t variable that can then * be used as a parameter to vTaskDelete to delete the task. * * \defgroup TaskHandle_t TaskHandle_t @@ -579,7 +579,7 @@ typedef enum * * Example usage: * @code{c} - * // Create an TaskParameters_t structure that defines the task to be created. + * // Create a TaskParameters_t structure that defines the task to be created. * static const TaskParameters_t xCheckTaskParameters = * { * vATask, // pvTaskCode - the function that implements the task. @@ -677,7 +677,7 @@ typedef enum * * Example usage: * @code{c} - * // Create an TaskParameters_t structure that defines the task to be created. + * // Create a TaskParameters_t structure that defines the task to be created. * // The StaticTask_t variable is only included in the structure when * // configSUPPORT_STATIC_ALLOCATION is set to 1. The PRIVILEGED_DATA macro can * // be used to force the variable into the RTOS kernel's privileged data area. @@ -1075,7 +1075,7 @@ BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, * // it itself. * if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY ) * { - * // The task has changed it's priority. + * // The task has changed its priority. * } * * // ... @@ -2157,7 +2157,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for * uxTaskGetSystemState() to be available. * - * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in + * uxTaskGetSystemState() populates a TaskStatus_t structure for each task in * the system. TaskStatus_t structures contain, among other things, members * for the task handle, task name, task priority, task state, and total amount * of run time consumed by the task. See the TaskStatus_t structure @@ -3307,7 +3307,7 @@ uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, /** * task. h * @code{c} - * BaseType_t xTaskNotifyStateClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToCLear ); + * BaseType_t xTaskNotifyStateClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToClear ); * * BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ); * @endcode diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c index b584c63e7..bd1654759 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c @@ -126,9 +126,9 @@ " restore_general_regs_first_task: \n" " subs r2, #32 \n" " ldmia r2!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ - " stmia r3!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " stmia r3!, {r4-r7} \n" /* Copy half of the hardware saved context on the task stack. */ " ldmia r2!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ - " stmia r3!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " stmia r3!, {r4-r7} \n" /* Copy rest half of the hardware saved context on the task stack. */ " subs r2, #48 \n" " ldmia r2!, {r4-r7} \n" /* Restore r8-r11. */ " mov r8, r4 \n" /* r8 = r4. */ @@ -402,9 +402,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " restore_general_regs: \n" " subs r2, #32 \n" " ldmia r2!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ - " stmia r3!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " stmia r3!, {r4-r7} \n" /* Copy half of the hardware saved context on the task stack. */ " ldmia r2!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ - " stmia r3!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " stmia r3!, {r4-r7} \n" /* Copy rest half of the hardware saved context on the task stack. */ " subs r2, #48 \n" " ldmia r2!, {r4-r7} \n" /* Restore r8-r11. */ " mov r8, r4 \n" /* r8 = r4. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c index d215f8f73..718119aad 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c @@ -121,9 +121,9 @@ " restore_general_regs_first_task: \n" " subs r1, #32 \n" " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context on the task stack. */ " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context on the task stack. */ " subs r1, #48 \n" " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ " mov r8, r4 \n" /* r8 = r4. */ @@ -375,9 +375,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " restore_general_regs: \n" " subs r1, #32 \n" " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context on the task stack. */ " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context on the task stack. */ " subs r1, #48 \n" " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ " mov r8, r4 \n" /* r8 = r4. */ diff --git a/portable/ARMv8M/secure/context/secure_context.c b/portable/ARMv8M/secure/context/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/ARMv8M/secure/context/secure_context.c +++ b/portable/ARMv8M/secure/context/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/CodeWarrior/HCS12/port.c b/portable/CodeWarrior/HCS12/port.c index 2d564cd66..fbff071ea 100644 --- a/portable/CodeWarrior/HCS12/port.c +++ b/portable/CodeWarrior/HCS12/port.c @@ -63,7 +63,7 @@ scheduler startup function. */ /* Calls to portENTER_CRITICAL() can be nested. When they are nested the critical section should not be left (i.e. interrupts should not be re-enabled) until the nesting depth reaches 0. This variable simply tracks the nesting -depth. Each task maintains it's own critical nesting depth variable so +depth. Each task maintains its own critical nesting depth variable so uxCriticalNesting is saved and restored from the task stack during a context switch. */ volatile UBaseType_t uxCriticalNesting = 0xff; diff --git a/portable/GCC/ARM_CM0/port.c b/portable/GCC/ARM_CM0/port.c index fd3229a76..a4f957796 100644 --- a/portable/GCC/ARM_CM0/port.c +++ b/portable/GCC/ARM_CM0/port.c @@ -689,7 +689,7 @@ static void prvTaskExitError( void ) } /* Shift the code by one before returning so it can be written directly - * into the the correct bit position of the attribute register. */ + * into the correct bit position of the attribute register. */ return( ulReturnValue << 1UL ); } diff --git a/portable/GCC/ARM_CM0/portasm.c b/portable/GCC/ARM_CM0/portasm.c index 179a71546..4896f654d 100644 --- a/portable/GCC/ARM_CM0/portasm.c +++ b/portable/GCC/ARM_CM0/portasm.c @@ -111,9 +111,9 @@ " restore_general_regs_first_task: \n" " subs r1, #32 \n" " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context on the task stack. */ " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context on the task stack. */ " subs r1, #48 \n" " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ " mov r8, r4 \n" /* r8 = r4. */ @@ -366,9 +366,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " restore_general_regs: \n" " subs r1, #32 \n" " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context on the task stack. */ " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context on the task stack. */ " subs r1, #48 \n" " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ " mov r8, r4 \n" /* r8 = r4. */ diff --git a/portable/GCC/ARM_CM23/non_secure/portasm.c b/portable/GCC/ARM_CM23/non_secure/portasm.c index b584c63e7..bd1654759 100644 --- a/portable/GCC/ARM_CM23/non_secure/portasm.c +++ b/portable/GCC/ARM_CM23/non_secure/portasm.c @@ -126,9 +126,9 @@ " restore_general_regs_first_task: \n" " subs r2, #32 \n" " ldmia r2!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ - " stmia r3!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " stmia r3!, {r4-r7} \n" /* Copy half of the hardware saved context on the task stack. */ " ldmia r2!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ - " stmia r3!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " stmia r3!, {r4-r7} \n" /* Copy rest half of the hardware saved context on the task stack. */ " subs r2, #48 \n" " ldmia r2!, {r4-r7} \n" /* Restore r8-r11. */ " mov r8, r4 \n" /* r8 = r4. */ @@ -402,9 +402,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " restore_general_regs: \n" " subs r2, #32 \n" " ldmia r2!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ - " stmia r3!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " stmia r3!, {r4-r7} \n" /* Copy half of the hardware saved context on the task stack. */ " ldmia r2!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ - " stmia r3!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " stmia r3!, {r4-r7} \n" /* Copy rest half of the hardware saved context on the task stack. */ " subs r2, #48 \n" " ldmia r2!, {r4-r7} \n" /* Restore r8-r11. */ " mov r8, r4 \n" /* r8 = r4. */ diff --git a/portable/GCC/ARM_CM23/secure/secure_context.c b/portable/GCC/ARM_CM23/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/GCC/ARM_CM23/secure/secure_context.c +++ b/portable/GCC/ARM_CM23/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c index d215f8f73..718119aad 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c @@ -121,9 +121,9 @@ " restore_general_regs_first_task: \n" " subs r1, #32 \n" " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context on the task stack. */ " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context on the task stack. */ " subs r1, #48 \n" " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ " mov r8, r4 \n" /* r8 = r4. */ @@ -375,9 +375,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " restore_general_regs: \n" " subs r1, #32 \n" " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context on the task stack. */ " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ - " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context on the task stack. */ " subs r1, #48 \n" " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ " mov r8, r4 \n" /* r8 = r4. */ diff --git a/portable/GCC/ARM_CM33/secure/secure_context.c b/portable/GCC/ARM_CM33/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/GCC/ARM_CM33/secure/secure_context.c +++ b/portable/GCC/ARM_CM33/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/GCC/ARM_CM35P/secure/secure_context.c b/portable/GCC/ARM_CM35P/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_context.c +++ b/portable/GCC/ARM_CM35P/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c index c8d3439b6..96d781d96 100644 --- a/portable/GCC/ARM_CM3_MPU/port.c +++ b/portable/GCC/ARM_CM3_MPU/port.c @@ -1206,7 +1206,7 @@ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) } /* Shift the code by one before returning so it can be written directly - * into the the correct bit position of the attribute register. */ + * into the correct bit position of the attribute register. */ return( ulReturnValue << 1UL ); } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c index 5a3527157..146798c0f 100644 --- a/portable/GCC/ARM_CM4_MPU/port.c +++ b/portable/GCC/ARM_CM4_MPU/port.c @@ -1350,7 +1350,7 @@ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) } /* Shift the code by one before returning so it can be written directly - * into the the correct bit position of the attribute register. */ + * into the correct bit position of the attribute register. */ return( ulReturnValue << 1UL ); } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM52/secure/secure_context.c b/portable/GCC/ARM_CM52/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/GCC/ARM_CM52/secure/secure_context.c +++ b/portable/GCC/ARM_CM52/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/GCC/ARM_CM55/secure/secure_context.c b/portable/GCC/ARM_CM55/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/GCC/ARM_CM55/secure/secure_context.c +++ b/portable/GCC/ARM_CM55/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/GCC/ARM_CM85/secure/secure_context.c b/portable/GCC/ARM_CM85/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/GCC/ARM_CM85/secure/secure_context.c +++ b/portable/GCC/ARM_CM85/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 56ff38384..f21ea49ae 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -489,7 +489,7 @@ static uint32_t prvGetMPURegionSizeEncoding( uint32_t ulActualMPURegionSize ) } /* Shift the code by one before returning so it can be written directly - * into the the correct bit position of the attribute register. */ + * into the correct bit position of the attribute register. */ return ulReturnValue << 1UL; } diff --git a/portable/GCC/ARM_STAR_MC3/secure/secure_context.c b/portable/GCC/ARM_STAR_MC3/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/GCC/ARM_STAR_MC3/secure/secure_context.c +++ b/portable/GCC/ARM_STAR_MC3/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/GCC/HCS12/port.c b/portable/GCC/HCS12/port.c index 4355a3f11..77c03801c 100644 --- a/portable/GCC/HCS12/port.c +++ b/portable/GCC/HCS12/port.c @@ -64,7 +64,7 @@ BaseType_t ATTR_NEAR xStartSchedulerNear( void ); /* Calls to portENTER_CRITICAL() can be nested. When they are nested the * critical section should not be left (i.e. interrupts should not be re-enabled) * until the nesting depth reaches 0. This variable simply tracks the nesting - * depth. Each task maintains it's own critical nesting depth variable so + * depth. Each task maintains its own critical nesting depth variable so * uxCriticalNesting is saved and restored from the task stack during a context * switch. */ volatile UBaseType_t uxCriticalNesting = 0x80; /* un-initialized */ diff --git a/portable/GCC/MicroBlaze/port.c b/portable/GCC/MicroBlaze/port.c index fb8b410be..7b987949a 100644 --- a/portable/GCC/MicroBlaze/port.c +++ b/portable/GCC/MicroBlaze/port.c @@ -63,7 +63,7 @@ #define portISR_STACK_FILL_VALUE 0x55555555 /* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task - * maintains it's own count, so this variable is saved as part of the task + * maintains its own count, so this variable is saved as part of the task * context. */ volatile UBaseType_t uxCriticalNesting = portINITIAL_NESTING_VALUE; @@ -235,7 +235,7 @@ void vPortYield( void ) /* Perform the context switch in a critical section to assure it is * not interrupted by the tick ISR. It is not a problem to do this as - * each task maintains it's own interrupt status. */ + * each task maintains its own interrupt status. */ portENTER_CRITICAL(); /* Jump directly to the yield function to ensure there is no diff --git a/portable/GCC/MicroBlazeV8/portmacro.h b/portable/GCC/MicroBlazeV8/portmacro.h index d23214ea4..e8e0f3686 100644 --- a/portable/GCC/MicroBlazeV8/portmacro.h +++ b/portable/GCC/MicroBlazeV8/portmacro.h @@ -322,7 +322,7 @@ void vApplicationSetupTimerInterrupt( void ); /* * This is an application defined callback function used to clear whichever - * interrupt was installed by the the vApplicationSetupTimerInterrupt() callback + * interrupt was installed by the vApplicationSetupTimerInterrupt() callback * function - in this case the interrupt generated by the AXI timer. It is * provided as an application callback because the kernel will run on lots of * different MicroBlaze and FPGA configurations - not all of which will have the diff --git a/portable/GCC/MicroBlazeV9/portmacro.h b/portable/GCC/MicroBlazeV9/portmacro.h index 1fb9c8259..c3556f94c 100644 --- a/portable/GCC/MicroBlazeV9/portmacro.h +++ b/portable/GCC/MicroBlazeV9/portmacro.h @@ -337,7 +337,7 @@ void vApplicationSetupTimerInterrupt( void ); /* * This is an application defined callback function used to clear whichever - * interrupt was installed by the the vApplicationSetupTimerInterrupt() callback + * interrupt was installed by the vApplicationSetupTimerInterrupt() callback * function - in this case the interrupt generated by the AXI timer. It is * provided as an application callback because the kernel will run on lots of * different MicroBlaze and FPGA configurations - not all of which will have the diff --git a/portable/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h b/portable/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h index 4d8a5fb53..25c1b7fba 100644 --- a/portable/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h +++ b/portable/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h @@ -27,7 +27,7 @@ */ /* - * The FreeRTOS kernel's RISC-V port is split between the the code that is + * The FreeRTOS kernel's RISC-V port is split between the code that is * common across all currently supported RISC-V chips (implementations of the * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: * diff --git a/portable/GCC/RISC-V/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h b/portable/GCC/RISC-V/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h index 3be456cb4..a9599395d 100644 --- a/portable/GCC/RISC-V/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h +++ b/portable/GCC/RISC-V/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h @@ -27,7 +27,7 @@ */ /* - * The FreeRTOS kernel's RISC-V port is split between the the code that is + * The FreeRTOS kernel's RISC-V port is split between the code that is * common across all currently supported RISC-V chips (implementations of the * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: * diff --git a/portable/GCC/RISC-V/chip_specific_extensions/RISCV_no_extensions/freertos_risc_v_chip_specific_extensions.h b/portable/GCC/RISC-V/chip_specific_extensions/RISCV_no_extensions/freertos_risc_v_chip_specific_extensions.h index 9f93824bd..a55d66a94 100644 --- a/portable/GCC/RISC-V/chip_specific_extensions/RISCV_no_extensions/freertos_risc_v_chip_specific_extensions.h +++ b/portable/GCC/RISC-V/chip_specific_extensions/RISCV_no_extensions/freertos_risc_v_chip_specific_extensions.h @@ -27,7 +27,7 @@ */ /* - * The FreeRTOS kernel's RISC-V port is split between the the code that is + * The FreeRTOS kernel's RISC-V port is split between the code that is * common across all currently supported RISC-V chips (implementations of the * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: * diff --git a/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h b/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h index 5b9ef4c06..f738a6a3d 100644 --- a/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h +++ b/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h @@ -27,7 +27,7 @@ */ /* - * The FreeRTOS kernel's RISC-V port is split between the the code that is + * The FreeRTOS kernel's RISC-V port is split between the code that is * common across all currently supported RISC-V chips (implementations of the * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: * diff --git a/portable/IAR/ARM_CM23/secure/secure_context.c b/portable/IAR/ARM_CM23/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/IAR/ARM_CM23/secure/secure_context.c +++ b/portable/IAR/ARM_CM23/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/IAR/ARM_CM33/secure/secure_context.c b/portable/IAR/ARM_CM33/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/IAR/ARM_CM33/secure/secure_context.c +++ b/portable/IAR/ARM_CM33/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/IAR/ARM_CM35P/secure/secure_context.c b/portable/IAR/ARM_CM35P/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_context.c +++ b/portable/IAR/ARM_CM35P/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c index 0441e0f0c..423d0a777 100644 --- a/portable/IAR/ARM_CM4F_MPU/port.c +++ b/portable/IAR/ARM_CM4F_MPU/port.c @@ -1139,7 +1139,7 @@ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) } /* Shift the code by one before returning so it can be written directly - * into the the correct bit position of the attribute register. */ + * into the correct bit position of the attribute register. */ return( ulReturnValue << 1UL ); } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM52/secure/secure_context.c b/portable/IAR/ARM_CM52/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/IAR/ARM_CM52/secure/secure_context.c +++ b/portable/IAR/ARM_CM52/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/IAR/ARM_CM55/secure/secure_context.c b/portable/IAR/ARM_CM55/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/IAR/ARM_CM55/secure/secure_context.c +++ b/portable/IAR/ARM_CM55/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/IAR/ARM_CM85/secure/secure_context.c b/portable/IAR/ARM_CM85/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/IAR/ARM_CM85/secure/secure_context.c +++ b/portable/IAR/ARM_CM85/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/IAR/ARM_STAR_MC3/secure/secure_context.c b/portable/IAR/ARM_STAR_MC3/secure/secure_context.c index a91e5e891..a7e13734d 100644 --- a/portable/IAR/ARM_STAR_MC3/secure/secure_context.c +++ b/portable/IAR/ARM_STAR_MC3/secure/secure_context.c @@ -349,7 +349,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl secureportREAD_PSPLIM( pucStackLimit ); - /* Ensure that task's context is loaded and the task is saving it's own + /* Ensure that task's context is loaded and the task is saving its own * context. */ if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) diff --git a/portable/IAR/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h b/portable/IAR/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h index 364fd5773..49c6479f0 100644 --- a/portable/IAR/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h +++ b/portable/IAR/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h @@ -27,7 +27,7 @@ */ /* - * The FreeRTOS kernel's RISC-V port is split between the the code that is + * The FreeRTOS kernel's RISC-V port is split between the code that is * common across all currently supported RISC-V chips (implementations of the * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: * diff --git a/portable/MPLAB/PIC32MEC14xx/ISR_Support.h b/portable/MPLAB/PIC32MEC14xx/ISR_Support.h index ce7c4ad63..ad6c91487 100644 --- a/portable/MPLAB/PIC32MEC14xx/ISR_Support.h +++ b/portable/MPLAB/PIC32MEC14xx/ISR_Support.h @@ -78,7 +78,7 @@ la k0, uxInterruptNesting lw s6, (k0) - /* If the nesting count is 0 then swap to the the system stack, otherwise + /* If the nesting count is 0 then swap to the system stack, otherwise the system stack is already being used. */ bne s6, zero, 1f nop diff --git a/portable/MPLAB/PIC32MX/ISR_Support.h b/portable/MPLAB/PIC32MX/ISR_Support.h index 0bff08fe1..b92838895 100644 --- a/portable/MPLAB/PIC32MX/ISR_Support.h +++ b/portable/MPLAB/PIC32MX/ISR_Support.h @@ -60,7 +60,7 @@ la k0, uxInterruptNesting lw s6, (k0) - /* If the nesting count is 0 then swap to the the system stack, otherwise + /* If the nesting count is 0 then swap to the system stack, otherwise the system stack is already being used. */ bne s6, zero, 1f nop diff --git a/portable/MPLAB/PIC32MZ/ISR_Support.h b/portable/MPLAB/PIC32MZ/ISR_Support.h index 292877f42..396e345a0 100644 --- a/portable/MPLAB/PIC32MZ/ISR_Support.h +++ b/portable/MPLAB/PIC32MZ/ISR_Support.h @@ -174,7 +174,7 @@ la k0, uxInterruptNesting lw s6, (k0) - /* If the nesting count is 0 then swap to the the system stack, otherwise + /* If the nesting count is 0 then swap to the system stack, otherwise the system stack is already being used. */ bne s6, zero, 1f nop diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c index 8620325ca..77c497a9b 100644 --- a/portable/RVDS/ARM_CM4_MPU/port.c +++ b/portable/RVDS/ARM_CM4_MPU/port.c @@ -1351,7 +1351,7 @@ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) } /* Shift the code by one before returning so it can be written directly - * into the the correct bit position of the attribute register. */ + * into the correct bit position of the attribute register. */ return( ulReturnValue << 1UL ); } /*-----------------------------------------------------------*/ diff --git a/stream_buffer.c b/stream_buffer.c index a4c6d268d..57ac1be06 100644 --- a/stream_buffer.c +++ b/stream_buffer.c @@ -272,7 +272,7 @@ static BaseType_t prvBytesInBufferMeetTriggerLevel( const StreamBuffer_t * const * the length and data bytes are written in two separate chunks, and we don't want * the reader to see the buffer as having grown until after all data is copied over. * This function takes a custom xHead value to indicate where to write to (necessary - * for chaining) and returns the the resulting xHead position. + * for chaining) and returns the resulting xHead position. * To mark the write as complete, manually set the buffer's xHead field with the * returned xHead from this function. */ @@ -314,7 +314,7 @@ static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, * the writer to see the buffer as having more free space until after all data is * copied over, especially if we have to abort the read due to insufficient receiving space. * This function takes a custom xTail value to indicate where to read from (necessary - * for chaining) and returns the the resulting xTail position. + * for chaining) and returns the resulting xTail position. * To mark the read as complete, manually set the buffer's xTail field with the * returned xTail from this function. */ diff --git a/tasks.c b/tasks.c index 76f6e5db9..43c9063c0 100644 --- a/tasks.c +++ b/tasks.c @@ -8849,7 +8849,7 @@ STATIC void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, * This is the kernel provided implementation of vApplicationGetIdleTaskMemory() * to provide the memory that is used by the Idle task. It is used when * configKERNEL_PROVIDED_STATIC_MEMORY is set to 1. The application can provide - * it's own implementation of vApplicationGetIdleTaskMemory by setting + * its own implementation of vApplicationGetIdleTaskMemory by setting * configKERNEL_PROVIDED_STATIC_MEMORY to 0 or leaving it undefined. */ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, @@ -8890,7 +8890,7 @@ STATIC void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, * This is the kernel provided implementation of vApplicationGetTimerTaskMemory() * to provide the memory that is used by the Timer service task. It is used when * configKERNEL_PROVIDED_STATIC_MEMORY is set to 1. The application can provide - * it's own implementation of vApplicationGetTimerTaskMemory by setting + * its own implementation of vApplicationGetTimerTaskMemory by setting * configKERNEL_PROVIDED_STATIC_MEMORY to 0 or leaving it undefined. */ void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, 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 04/10] 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 05/10] 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 06/10] 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 07/10] 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 08/10] 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, From 7625c72410ebefb18b2b3670c4eba951edd87ca6 Mon Sep 17 00:00:00 2001 From: Jeff Tenney Date: Wed, 26 Aug 2026 09:38:52 -0700 Subject: [PATCH 09/10] Reduce SVCall priority on ARMv7-M with MPU (#1470) Restore the original SVCall priority for the ARMv7-M MPU ports from before #832. This change reduces the SVCall preemption priority from zero (the highest) to a priority just higher than configMAX_SYSCALL_INTERRUPT_PRIORITY (numerically lower). --------- Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --- portable/GCC/ARM_CM3_MPU/port.c | 11 ++++++----- portable/GCC/ARM_CM4_MPU/port.c | 10 ++++++---- portable/IAR/ARM_CM4F_MPU/port.c | 8 +++++--- portable/RVDS/ARM_CM4_MPU/port.c | 11 ++++++----- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c index 96d781d96..6b7ed02a0 100644 --- a/portable/GCC/ARM_CM3_MPU/port.c +++ b/portable/GCC/ARM_CM3_MPU/port.c @@ -96,12 +96,14 @@ typedef void ( * portISR_t )( void ); #define portPERIPHERALS_START_ADDRESS 0x40000000UL #define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL -/* Constants required to access and manipulate the SysTick. */ +/* Constants required to access and manipulate the SysTick and other FreeRTOS + * interrupts. */ #define portNVIC_SYSTICK_INT ( 0x00000002UL ) #define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) @@ -877,12 +879,11 @@ BaseType_t xPortStartScheduler( void ) } #endif /* configASSERT_DEFINED */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; - + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; /* Configure the regions in the MPU that are common to all tasks. */ prvSetupMPU(); diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c index 146798c0f..e1a70c511 100644 --- a/portable/GCC/ARM_CM4_MPU/port.c +++ b/portable/GCC/ARM_CM4_MPU/port.c @@ -106,12 +106,14 @@ typedef void ( * portISR_t )( void ); #define portPERIPHERALS_START_ADDRESS 0x40000000UL #define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL -/* Constants required to access and manipulate the SysTick. */ +/* Constants required to access and manipulate the SysTick and other FreeRTOS + * interrupts. */ #define portNVIC_SYSTICK_INT ( 0x00000002UL ) #define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */ @@ -965,11 +967,11 @@ BaseType_t xPortStartScheduler( void ) } #endif /* configASSERT_DEFINED */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; /* Configure the regions in the MPU that are common to all tasks. */ prvSetupMPU(); diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c index 423d0a777..a3b6517ef 100644 --- a/portable/IAR/ARM_CM4F_MPU/port.c +++ b/portable/IAR/ARM_CM4F_MPU/port.c @@ -120,9 +120,11 @@ typedef void ( * portISR_t )( void ); #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) +/* Constants to manipulate FreeRTOS interrupt priorities. */ #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants used to check the installation of the FreeRTOS interrupt handlers. */ #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xE000ED08 ) ) @@ -862,11 +864,11 @@ BaseType_t xPortStartScheduler( void ) } #endif /* configASSERT_DEFINED */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; /* Configure the regions in the MPU that are common to all tasks. */ prvSetupMPU(); diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c index 77c497a9b..7cdf3ea87 100644 --- a/portable/RVDS/ARM_CM4_MPU/port.c +++ b/portable/RVDS/ARM_CM4_MPU/port.c @@ -95,13 +95,15 @@ typedef void ( * portISR_t )( void ); #define portPERIPHERALS_START_ADDRESS 0x40000000UL #define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL -/* Constants required to access and manipulate the SysTick. */ +/* Constants required to access and manipulate the SysTick and other FreeRTOS + * interrupts. */ #define portNVIC_SYSTICK_CLK ( 0x00000004UL ) #define portNVIC_SYSTICK_INT ( 0x00000002UL ) #define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */ @@ -966,12 +968,11 @@ BaseType_t xPortStartScheduler( void ) } #endif /* configASSERT_DEFINED */ - /* Make PendSV and SysTick the same priority as the kernel, and the SVC - * handler highest priority so it can be used to exit a critical section - * (where lower priorities are masked). */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; /* Configure the regions in the MPU that are common to all tasks. */ prvSetupMPU(); From 8be86d4a24fd4091f8f4192018423ab590f408db Mon Sep 17 00:00:00 2001 From: Ian Thompson <101299961+ianstcdns@users.noreply.github.com> Date: Wed, 26 Aug 2026 10:09:47 -0700 Subject: [PATCH 10/10] Optional PRIVILEGED_DATA wrapper + Partner-Supported-Ports submodule update (#1433) - Instead, when MPU wrappers are not used, allow port to override PRIVILEGED_FUNCTION, PRIVILEGED_DATA, or FREERTOS_SYSTEM_CALL selectively, permitting custom section placement at link-time. - Allows critical data to be placed in port-specific location for improved performance, notably for cache-coherent SMP. - Does not require enabling the full MPU wrappers. --- include/mpu_wrappers.h | 14 +++++++++++--- portable/ThirdParty/Partner-Supported-Ports | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/mpu_wrappers.h b/include/mpu_wrappers.h index ebbd5f940..69e6cbb40 100644 --- a/include/mpu_wrappers.h +++ b/include/mpu_wrappers.h @@ -286,9 +286,17 @@ #else /* portUSING_MPU_WRAPPERS */ - #define PRIVILEGED_FUNCTION - #define PRIVILEGED_DATA - #define FREERTOS_SYSTEM_CALL + #ifndef PRIVILEGED_FUNCTION + #define PRIVILEGED_FUNCTION + #endif + + #ifndef PRIVILEGED_DATA + #define PRIVILEGED_DATA + #endif + + #ifndef FREERTOS_SYSTEM_CALL + #define FREERTOS_SYSTEM_CALL + #endif #endif /* portUSING_MPU_WRAPPERS */ diff --git a/portable/ThirdParty/Partner-Supported-Ports b/portable/ThirdParty/Partner-Supported-Ports index abc22103e..fccbbce9b 160000 --- a/portable/ThirdParty/Partner-Supported-Ports +++ b/portable/ThirdParty/Partner-Supported-Ports @@ -1 +1 @@ -Subproject commit abc22103e1e6634b33457d4127bff1ab62f27f90 +Subproject commit fccbbce9bd7e227ee211b01fdbbcf133dc3a474a