mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2026-10-10 08:02:57 -04:00
Guard xTaskCreate() stack allocation against size_t overflow
uxStackDepth * sizeof(StackType_t) was computed without an overflow check before being passed to pvPortMallocStack(). On a target where size_t and StackType_t are both 32 bits, a large enough uxStackDepth wraps the multiplication to a small allocation, while prvInitialiseNewTask() still uses the original, larger uxStackDepth for stack pointer arithmetic (pxStack[uxStackDepth - 1] and the end-of-stack pointer), producing an out-of-bounds access. Add tskSTACK_DEPTH_WILL_OVERFLOW() and check it at both dynamic allocation sites in prvCreateTask() (portSTACK_GROWTH > 0 and <= 0), falling back to the existing NULL-allocation failure path rather than calling pvPortMallocStack() with a size that has already wrapped. Verified with a standalone reproduction of the exact 32-bit arithmetic against the depth from the report (0x40000020 words), confirming the wrap without the guard and rejection with it, and compiled tasks.c clean under the POSIX/Linux port (portSTACK_GROWTH <= 0 branch).
This commit is contained in:
parent
8be86d4a24
commit
da9313a6fc
1 changed files with 42 additions and 8 deletions
34
tasks.c
34
tasks.c
|
|
@ -120,6 +120,20 @@
|
||||||
*/
|
*/
|
||||||
#define tskSTACK_FILL_BYTE ( 0xa5U )
|
#define tskSTACK_FILL_BYTE ( 0xa5U )
|
||||||
|
|
||||||
|
/* The largest value representable by size_t, used to guard the stack
|
||||||
|
* allocation size calculation below against unsigned wraparound. Written
|
||||||
|
* this way (rather than SIZE_MAX from <stdint.h>) to match the existing
|
||||||
|
* pattern used for the same purpose in the secure_heap.c files under
|
||||||
|
* portable/, e.g. portable/GCC/ARM_CM33/secure/secure_heap.c. */
|
||||||
|
#define tskSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||||
|
|
||||||
|
/* True if allocating uxStackDepth words of StackType_t would overflow
|
||||||
|
* size_t, which would otherwise silently truncate to an undersized
|
||||||
|
* allocation while task initialisation continues to use the original,
|
||||||
|
* larger uxStackDepth for stack pointer arithmetic. */
|
||||||
|
#define tskSTACK_DEPTH_WILL_OVERFLOW( uxStackDepth ) \
|
||||||
|
( ( ( size_t ) ( uxStackDepth ) ) > ( tskSIZE_MAX / sizeof( StackType_t ) ) )
|
||||||
|
|
||||||
/* Bits used to record how a task's stack and TCB were allocated. */
|
/* Bits used to record how a task's stack and TCB were allocated. */
|
||||||
#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 )
|
#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 )
|
||||||
#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 )
|
#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 )
|
||||||
|
|
@ -1657,10 +1671,20 @@ STATIC void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
|
||||||
/* Allocate space for the stack used by the task being created.
|
/* Allocate space for the stack used by the task being created.
|
||||||
* The base of the stack memory stored in the TCB so the task can
|
* The base of the stack memory stored in the TCB so the task can
|
||||||
* be deleted later if required. */
|
* be deleted later if required. */
|
||||||
|
if( tskSTACK_DEPTH_WILL_OVERFLOW( uxStackDepth ) )
|
||||||
|
{
|
||||||
|
/* uxStackDepth * sizeof( StackType_t ) would overflow size_t
|
||||||
|
* and wrap to an undersized allocation. Treat this the same
|
||||||
|
* as any other allocation failure. */
|
||||||
|
pxNewTCB->pxStack = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
|
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
|
||||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||||
pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) uxStackDepth ) * sizeof( StackType_t ) ) );
|
pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) uxStackDepth ) * sizeof( StackType_t ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
if( pxNewTCB->pxStack == NULL )
|
if( pxNewTCB->pxStack == NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -1675,10 +1699,20 @@ STATIC void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
|
||||||
StackType_t * pxStack;
|
StackType_t * pxStack;
|
||||||
|
|
||||||
/* Allocate space for the stack used by the task being created. */
|
/* Allocate space for the stack used by the task being created. */
|
||||||
|
if( tskSTACK_DEPTH_WILL_OVERFLOW( uxStackDepth ) )
|
||||||
|
{
|
||||||
|
/* uxStackDepth * sizeof( StackType_t ) would overflow size_t
|
||||||
|
* and wrap to an undersized allocation. Treat this the same
|
||||||
|
* as any other allocation failure. */
|
||||||
|
pxStack = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
|
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
|
||||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||||
pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) uxStackDepth ) * sizeof( StackType_t ) ) );
|
pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) uxStackDepth ) * sizeof( StackType_t ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
if( pxStack != NULL )
|
if( pxStack != NULL )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue