@@ -1653,77 +1653,95 @@ STATIC void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
16531653 {
16541654 TCB_t * pxNewTCB ;
16551655
1656- /* If the stack grows down then allocate the stack then the TCB so the stack
1657- * does not grow into the TCB. Likewise if the stack grows up then allocate
1658- * the TCB then the stack. */
1659- #if ( portSTACK_GROWTH > 0 )
1660- {
1661- /* Allocate space for the TCB. Where the memory comes from depends on
1662- * the implementation of the port malloc function and whether or not static
1663- * allocation is being used. */
1664- /* MISRA Ref 11.5.1 [Malloc memory assignment] */
1665- /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
1666- /* coverity[misra_c_2012_rule_11_5_violation] */
1667- pxNewTCB = ( TCB_t * ) pvPortMalloc ( sizeof ( TCB_t ) );
1668-
1669- if ( pxNewTCB != NULL )
1656+ /* Guard against the stack size calculation overflowing. The stack is
1657+ * allocated as ( ( size_t ) uxStackDepth ) * sizeof( StackType_t ). If a
1658+ * caller-supplied uxStackDepth is large enough that this product wraps
1659+ * size_t, the allocation is far smaller than requested while
1660+ * prvInitialiseNewTask() still computes the top of stack from the full
1661+ * uxStackDepth, causing out-of-bounds writes when the initial stack frame
1662+ * is written. The wrap is detected by multiplying and dividing back:
1663+ * if dividing the byte size by sizeof( StackType_t ) does not recover
1664+ * uxStackDepth then the multiplication overflowed. Leave pxNewTCB NULL
1665+ * and skip allocation instead of under-allocating, so the failure is
1666+ * reported through the single return at the end of the function. */
1667+ if ( ( ( size_t ) uxStackDepth ) != ( ( ( ( size_t ) uxStackDepth ) * sizeof ( StackType_t ) ) / sizeof ( StackType_t ) ) )
1668+ {
1669+ pxNewTCB = NULL ;
1670+ }
1671+ else
1672+ {
1673+ /* If the stack grows down then allocate the stack then the TCB so the stack
1674+ * does not grow into the TCB. Likewise if the stack grows up then allocate
1675+ * the TCB then the stack. */
1676+ #if ( portSTACK_GROWTH > 0 )
16701677 {
1671- ( void ) memset ( ( void * ) pxNewTCB , 0x00 , sizeof ( TCB_t ) );
1672-
1673- /* Allocate space for the stack used by the task being created.
1674- * The base of the stack memory stored in the TCB so the task can
1675- * be deleted later if required. */
1678+ /* Allocate space for the TCB. Where the memory comes from depends on
1679+ * the implementation of the port malloc function and whether or not static
1680+ * allocation is being used. */
16761681 /* MISRA Ref 11.5.1 [Malloc memory assignment] */
16771682 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
16781683 /* coverity[misra_c_2012_rule_11_5_violation] */
1679- pxNewTCB -> pxStack = ( StackType_t * ) pvPortMallocStack ( ( ( ( size_t ) uxStackDepth ) * sizeof ( StackType_t ) ) );
1684+ pxNewTCB = ( TCB_t * ) pvPortMalloc ( sizeof ( TCB_t ) );
16801685
1681- if ( pxNewTCB -> pxStack = = NULL )
1686+ if ( pxNewTCB ! = NULL )
16821687 {
1683- /* Could not allocate the stack. Delete the allocated TCB. */
1684- vPortFree ( pxNewTCB );
1685- pxNewTCB = NULL ;
1686- }
1687- }
1688- }
1689- #else /* portSTACK_GROWTH */
1690- {
1691- StackType_t * pxStack ;
1688+ ( void ) memset ( ( void * ) pxNewTCB , 0x00 , sizeof ( TCB_t ) );
16921689
1693- /* Allocate space for the stack used by the task being created. */
1694- /* MISRA Ref 11.5.1 [Malloc memory assignment] */
1695- /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
1696- /* coverity[misra_c_2012_rule_11_5_violation] */
1697- pxStack = ( StackType_t * ) pvPortMallocStack ( ( ( ( size_t ) uxStackDepth ) * sizeof ( StackType_t ) ) );
1690+ /* Allocate space for the stack used by the task being created.
1691+ * The base of the stack memory stored in the TCB so the task can
1692+ * be deleted later if required. */
1693+ /* MISRA Ref 11.5.1 [Malloc memory assignment] */
1694+ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
1695+ /* coverity[misra_c_2012_rule_11_5_violation] */
1696+ pxNewTCB -> pxStack = ( StackType_t * ) pvPortMallocStack ( ( ( ( size_t ) uxStackDepth ) * sizeof ( StackType_t ) ) );
16981697
1699- if ( pxStack != NULL )
1698+ if ( pxNewTCB -> pxStack == NULL )
1699+ {
1700+ /* Could not allocate the stack. Delete the allocated TCB. */
1701+ vPortFree ( pxNewTCB );
1702+ pxNewTCB = NULL ;
1703+ }
1704+ }
1705+ }
1706+ #else /* portSTACK_GROWTH */
17001707 {
1701- /* Allocate space for the TCB. */
1708+ StackType_t * pxStack ;
1709+
1710+ /* Allocate space for the stack used by the task being created. */
17021711 /* MISRA Ref 11.5.1 [Malloc memory assignment] */
17031712 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
17041713 /* coverity[misra_c_2012_rule_11_5_violation] */
1705- pxNewTCB = ( TCB_t * ) pvPortMalloc ( sizeof ( TCB_t ) );
1714+ pxStack = ( StackType_t * ) pvPortMallocStack ( ( ( ( size_t ) uxStackDepth ) * sizeof ( StackType_t ) ) );
17061715
1707- if ( pxNewTCB != NULL )
1716+ if ( pxStack != NULL )
17081717 {
1709- ( void ) memset ( ( void * ) pxNewTCB , 0x00 , sizeof ( TCB_t ) );
1718+ /* Allocate space for the TCB. */
1719+ /* MISRA Ref 11.5.1 [Malloc memory assignment] */
1720+ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
1721+ /* coverity[misra_c_2012_rule_11_5_violation] */
1722+ pxNewTCB = ( TCB_t * ) pvPortMalloc ( sizeof ( TCB_t ) );
17101723
1711- /* Store the stack location in the TCB. */
1712- pxNewTCB -> pxStack = pxStack ;
1724+ if ( pxNewTCB != NULL )
1725+ {
1726+ ( void ) memset ( ( void * ) pxNewTCB , 0x00 , sizeof ( TCB_t ) );
1727+
1728+ /* Store the stack location in the TCB. */
1729+ pxNewTCB -> pxStack = pxStack ;
1730+ }
1731+ else
1732+ {
1733+ /* The stack cannot be used as the TCB was not created. Free
1734+ * it again. */
1735+ vPortFreeStack ( pxStack );
1736+ }
17131737 }
17141738 else
17151739 {
1716- /* The stack cannot be used as the TCB was not created. Free
1717- * it again. */
1718- vPortFreeStack ( pxStack );
1740+ pxNewTCB = NULL ;
17191741 }
17201742 }
1721- else
1722- {
1723- pxNewTCB = NULL ;
1724- }
1743+ #endif /* portSTACK_GROWTH */
17251744 }
1726- #endif /* portSTACK_GROWTH */
17271745
17281746 if ( pxNewTCB != NULL )
17291747 {
0 commit comments