Skip to content

Commit 88b6967

Browse files
authored
Merge branch 'FreeRTOS:main' into semiclon
2 parents 4d1cb1c + 92bfb86 commit 88b6967

47 files changed

Lines changed: 1912 additions & 788 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

History.txt

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,140 @@
11
Documentation and download available at https://www.FreeRTOS.org/
22

3+
Changes between FreeRTOS V11.3.0 and FreeRTOS V11.3.1 released August 2026
4+
5+
+ Add Symmetric Multiprocessing (SMP) support to the Armv8-M ports for the
6+
GCC, ArmClang and IAR toolchains. This adds per core critical nesting
7+
state, spinlocks, inter-core yield and wakeup using SEV/WFE, primary and
8+
secondary core bring up synchronization, and a core safe PendSV context
9+
switch. Single core builds are unchanged. We thank @AhmedIsmail02 for
10+
their contribution.
11+
+ Add new xTaskPeriodicDelay API for periodic tasks. It supersedes
12+
xTaskDelayUntil by preventing run away of pxPreviousWakeTime, catching up
13+
skipped periods immediately while returning the number of periods skipped,
14+
and returning 0 when not enough ticks have elapsed. We thank @ntd for
15+
their contribution.
16+
+ Add uxTaskCallForEachTask API, which invokes a caller supplied callback
17+
for each task in the system, and refactor uxTaskGetSystemState to use it.
18+
We thank @DRNadler for their contribution.
19+
+ Add configIDLE_AFFINITY configuration option, which pins each Idle task to
20+
its corresponding core in SMP systems. It defaults to 0, which allows the
21+
scheduler to run Idle tasks on any available core. We thank @rus084 for
22+
their contribution.
23+
+ Add validation to SecureContext_AllocateContext in the ARMv8-M secure side
24+
ports to ensure that the requested secure stack size plus the stack seal
25+
size does not overflow before allocating. We thank Jordan Mecom (Block,
26+
Inc.) for reporting this issue.
27+
+ Add assertions to vQueueDelete to check that no tasks are blocked on the
28+
queue being deleted.
29+
+ Add a link to the FreeRTOS Kernel threat model in SECURITY.md.
30+
+ Add documentation clarifying that the MemoryRegion_t ulParameters macros
31+
are port specific, so applications must use the tskMPU_REGION_* or
32+
portMPU_REGION_* values that match their MPU port. We thank @Old-Ding for
33+
their contribution.
34+
+ Add a comment documenting that a privileged task must revoke access
35+
permissions before deleting a kernel object when using Access Control
36+
Lists.
37+
+ Update the ARM_CRx_No_GIC port to declare vPortYield as a weak symbol so
38+
that devices with a dedicated software interrupt register can substitute
39+
their own yield trigger. The default behavior is unchanged. We thank
40+
@maximdeclercq for their contribution.
41+
+ Update the FreeRTOSConfig.h template to use a 32-bit tick type, which
42+
avoids compiler warnings on Windows where a 64-bit tick resolves to
43+
unsigned long long.
44+
+ Update the deprecated CMake configuration warning to use INTERFACE rather
45+
than PUBLIC for the freertos_config interface library. We thank @Isla-jq
46+
for their contribution.
47+
+ Fix vPortFreeSecureContext in the ARMv8-M ports to read xSecureContext at
48+
the correct offset. When the MPU is enabled, the first item in the TCB is
49+
the stored context location rather than the top of stack, so
50+
xSecureContext is located at a negative offset from that position.
51+
+ Fix SecureContext_AllocateContext in the ARMv8-M secure side ports to
52+
reject a secure stack size smaller than the stack seal size.
53+
+ Fix SecureContext_FreeContext in the ARMv8-M secure side ports to refuse
54+
to free the secure context that is currently loaded, as indicated by
55+
PSPLIM. Freeing it left the running task referencing freed secure memory.
56+
The task handle supplied by the non-secure side is untrusted, so it is
57+
now used only as an additional ownership check.
58+
+ Fix the ARMv8-M ports to service the portSVC_START_SCHEDULER and
59+
portSVC_FREE_SECURE_CONTEXT supervisor calls only when they are raised
60+
from privileged code. When the MPU is enabled, both requests are now
61+
ignored unless the calling program counter lies within the privileged
62+
functions section.
63+
+ Fix a type confusion in xQueueAddToSet by verifying that the object
64+
passed as the queue set really is a queue set, that is, that its item
65+
size is sizeof( Queue_t * ). Passing an ordinary queue now returns
66+
pdFAIL rather than allowing prvNotifyQueueSetContainer to copy item size
67+
bytes from a single pointer on the stack.
68+
+ Fix xTimerGenericCommandFromTask to validate the lower bound of
69+
xCommandID in addition to the existing upper bound, so that only the
70+
valid task command range from tmrCOMMAND_START_DONT_TRACE to
71+
tmrCOMMAND_DELETE is accepted. Rejected commands return pdFAIL, and
72+
behavior for valid commands and for xTimerGenericCommandFromISR is
73+
unchanged.
74+
+ Fix a kernel object pool entry leak by adding an MPU wrapper for the
75+
xTimerDelete API, so that the pool index is freed when a timer is deleted
76+
with MPU wrappers version 2.
77+
+ Fix the MPU wrapper macro mapping for the ARMv8-M ports.
78+
+ Fix silently failing critical sections in unprivileged tasks by
79+
disallowing configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS with MPU wrappers
80+
version 2 in the ARMv7-M MPU ports. The option now defaults to 0 under
81+
version 2, and explicitly setting it to 1 raises a compile time error.
82+
Behavior with MPU wrappers version 1 is unchanged.
83+
+ Fix a time of check to time of use race condition in vTaskListTasks, where
84+
reading the volatile task count twice allowed a task to be created between
85+
the reads, resulting in an undersized allocation and a possible buffer
86+
overflow in uxTaskGetSystemState. We thank @srpatcha for their
87+
contribution.
88+
+ Fix a spurious heap_5 assertion when configENABLE_HEAP_PROTECTOR is 1 and
89+
an allocation cannot be satisfied. The free block search reaching the end
90+
marker is a normal out of memory condition, so pvPortMalloc now returns
91+
NULL and invokes the malloc failed hook instead of asserting.
92+
+ Fix batching stream buffers to unblock a receiver only after the buffered
93+
byte count exceeds, rather than reaches, the trigger level. Previously a
94+
receiver could be woken early and xStreamBufferReceive could return 0
95+
bytes. Stream buffer and message buffer semantics are unchanged. We thank
96+
@officialasishkumar for their contribution.
97+
+ Fix MISRA C 2012 Rule 20.4 violation by replacing `#define static` with a
98+
STATIC macro, which also keeps the static variables in
99+
vApplicationGetIdleTaskMemory and vApplicationGetPassiveIdleTaskMemory
100+
static when portREMOVE_STATIC_QUALIFIER is defined. We thank @elsonwei for
101+
their contribution.
102+
+ Fix undefined behavior in the MSVC-MingW port caused by left shifting a
103+
signed int by 31 or more bits.
104+
+ Fix a duplicate Doxygen \defgroup identifier by giving
105+
uxTaskBasePriorityGet its own group instead of reusing the
106+
uxTaskPriorityGet group.
107+
+ Fix the incorrect #endif comment after vPortSetupTimerInterrupt in the GCC
108+
and IAR RISC-V ports, which duplicated configMTIME_BASE_ADDRESS and
109+
omitted configMTIMECMP_BASE_ADDRESS. We thank @cuiweixie for their
110+
contribution.
111+
+ Fix incorrect #endif comments in croutine.c and queue.c, which reversed
112+
the configUSE_CO_ROUTINES condition and named the wrong configuration
113+
option for configSUPPORT_DYNAMIC_ALLOCATION. We thank @Zepp-Hanzj for
114+
their contribution.
115+
+ Fix the configLIST_VOLATILE #endif comment and the documented parameter
116+
names for uxListRemove in include/list.h. We thank @rakeshr-source for
117+
their contribution.
118+
+ Fix the type and timeout values used in the xStreamBufferSend and
119+
xMessageBufferSend documentation examples. We thank @Isla-jq for their
120+
contribution.
121+
+ Fix copy and paste comment typos in xTaskGetApplicationTaskTag and
122+
xTaskGetApplicationTaskTagFromISR, and a typo in the
123+
xTaskGenericNotifyWait comment. We thank @wanghengZzz for their
124+
contributions.
125+
+ Fix comment typos in the queue.h, list.h and task.h documentation,
126+
including the xQueueReceiveFromISR and xQueueGenericSend examples, the
127+
listGET_ITEM_VALUE_OF_HEAD_ENTRY \page tag, and the uxIndexToCLear typo.
128+
We thank @zepp-chen for their contribution.
129+
+ Fix the FreeRTOSConfig.h template path referenced in README.md. We thank
130+
@IClementI for their contribution.
131+
+ Fix the missing V prefix in the release_tag and namespace-prefix inputs of
132+
the auto release workflow.
133+
+ Fix long path failures in the Windows kernel demo builds by enabling
134+
Windows long path support in CI.
135+
+ Remove an unnecessary const variable from the GCC and IAR RISC-V ports. We
136+
thank @IClementI for their contribution.
137+
3138
Changes between FreeRTOS V11.2.0 and FreeRTOS V11.3.0 released March 2026
4139

5140
+ Correct minor mistakes in code comments in event_groups.c, include/queue.h,

portable/ARMv8M/non_secure/port.c

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,6 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
11091109
{
11101110
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
11111111
#if defined( __ARMCC_VERSION )
1112-
11131112
/* Declaration when these variable are defined in code instead of being
11141113
* exported from linker scripts. */
11151114
extern uint32_t * __syscalls_flash_start__;
@@ -1121,6 +1120,19 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
11211120
#endif /* defined( __ARMCC_VERSION ) */
11221121
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
11231122

1123+
#if ( configENABLE_MPU == 1 )
1124+
#if defined( __ARMCC_VERSION )
1125+
/* Declaration when these variable are defined in code instead of being
1126+
* exported from linker scripts. */
1127+
extern uint32_t * __privileged_functions_start__;
1128+
extern uint32_t * __privileged_functions_end__;
1129+
#else
1130+
/* Declaration when these variable are exported from linker scripts. */
1131+
extern uint32_t __privileged_functions_start__[];
1132+
extern uint32_t __privileged_functions_end__[];
1133+
#endif /* defined( __ARMCC_VERSION ) */
1134+
#endif /* configENABLE_MPU == 1 */
1135+
11241136
uint32_t ulPC;
11251137

11261138
#if ( configENABLE_TRUSTZONE == 1 )
@@ -1170,39 +1182,54 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
11701182
break;
11711183

11721184
case portSVC_FREE_SECURE_CONTEXT:
1185+
#if ( configENABLE_MPU == 1 )
1186+
if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
1187+
( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
1188+
{
1189+
#endif /* configENABLE_MPU */
1190+
/* R0 contains TCB being freed and R1 contains the secure
1191+
* context handle to be freed. */
1192+
ulR0 = pulCallerStackAddress[ 0 ];
1193+
ulR1 = pulCallerStackAddress[ 1 ];
11731194

1174-
/* R0 contains TCB being freed and R1 contains the secure
1175-
* context handle to be freed. */
1176-
ulR0 = pulCallerStackAddress[ 0 ];
1177-
ulR1 = pulCallerStackAddress[ 1 ];
1178-
1179-
/* Free the secure context. */
1180-
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
1195+
/* Free the secure context. */
1196+
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
1197+
#if ( configENABLE_MPU == 1 )
1198+
}
1199+
#endif /* configENABLE_MPU */
11811200
break;
11821201
#endif /* configENABLE_TRUSTZONE */
11831202

11841203
case portSVC_START_SCHEDULER:
1185-
#if ( configENABLE_TRUSTZONE == 1 )
1204+
#if ( configENABLE_MPU == 1 )
1205+
if( ( ulPC >= ( uint32_t ) __privileged_functions_start__ ) &&
1206+
( ulPC <= ( uint32_t ) __privileged_functions_end__ ) )
11861207
{
1187-
/* De-prioritize the non-secure exceptions so that the
1188-
* non-secure pendSV runs at the lowest priority. */
1189-
SecureInit_DePrioritizeNSExceptions();
1208+
#endif /* configENABLE_MPU */
1209+
#if ( configENABLE_TRUSTZONE == 1 )
1210+
{
1211+
/* De-prioritize the non-secure exceptions so that the
1212+
* non-secure pendSV runs at the lowest priority. */
1213+
SecureInit_DePrioritizeNSExceptions();
11901214

1191-
/* Initialize the secure context management system. */
1192-
SecureContext_Init();
1193-
}
1194-
#endif /* configENABLE_TRUSTZONE */
1215+
/* Initialize the secure context management system. */
1216+
SecureContext_Init();
1217+
}
1218+
#endif /* configENABLE_TRUSTZONE */
11951219

1196-
#if ( configENABLE_FPU == 1 )
1197-
{
1198-
/* Setup the Floating Point Unit (FPU). */
1199-
prvSetupFPU();
1200-
}
1201-
#endif /* configENABLE_FPU */
1220+
#if ( configENABLE_FPU == 1 )
1221+
{
1222+
/* Setup the Floating Point Unit (FPU). */
1223+
prvSetupFPU();
1224+
}
1225+
#endif /* configENABLE_FPU */
12021226

1203-
/* Setup the context of the first task so that the first task starts
1204-
* executing. */
1205-
vRestoreContextOfFirstTask();
1227+
/* Setup the context of the first task so that the first task starts
1228+
* executing. */
1229+
vRestoreContextOfFirstTask();
1230+
#if ( configENABLE_MPU == 1 )
1231+
}
1232+
#endif /* configENABLE_MPU */
12061233
break;
12071234

12081235
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )

portable/ARMv8M/secure/context/secure_context.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
214214
if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS )
215215
{
216216
/* Allocate the stack space if possible. */
217-
if( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) )
217+
if( ( ulSecureStackSize < securecontextSTACK_SEAL_SIZE ) ||
218+
( ulSecureStackSize > ( UINT32_MAX - securecontextSTACK_SEAL_SIZE ) ) )
218219
{
220+
/* Reject stacks that are too small (the CONTROL word would be
221+
* written before the allocation, corrupting the secure heap)
222+
* and sizes that would overflow when the seal size is added. */
219223
pucStackMemory = NULL;
220224
}
221225
else
@@ -286,9 +290,12 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl
286290
void * pvTaskHandle )
287291
{
288292
uint32_t ulIPSR, ulSecureContextIndex;
293+
uint8_t * pucStackLimit;
289294

290-
/* Read the Interrupt Program Status Register (IPSR) value. */
295+
/* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
296+
* Register (PSPLIM) value. */
291297
secureportREAD_IPSR( ulIPSR );
298+
secureportREAD_PSPLIM( pucStackLimit );
292299

293300
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
294301
* when the processor is running in the Thread Mode. */
@@ -300,8 +307,14 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl
300307
ulSecureContextIndex = xSecureContextHandle - 1UL;
301308

302309
/* Ensure that the secure context being deleted is associated with
303-
* the task. */
304-
if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
310+
* the task and is NOT the currently-loaded context. Freeing a
311+
* context whose stack is currently loaded in PSPLIM would leave the
312+
* running task referencing freed secure memory (use-after-free).
313+
* pvTaskHandle is supplied by the non-secure side and is untrusted,
314+
* so it is used only as an additional ownership match, not as
315+
* authority. */
316+
if( ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) &&
317+
( xSecureContexts[ ulSecureContextIndex ].pucStackLimit != pucStackLimit ) )
305318
{
306319
/* Free the stack space. */
307320
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );

0 commit comments

Comments
 (0)