forked from epagris/FreeRTOS-Kernel
		
	Remove local stack variable form MPU wrappers
It was possible for a third party that had already independently gained the ability to execute injected code to achieve further privilege escalation by branching directly inside a FreeRTOS MPU API wrapper function with a manually crafted stack frame. This commit removes the local stack variable `xRunningPrivileged` so that a manually crafted stack frame cannot be used for privilege escalation by branching directly inside a FreeRTOS MPU API wrapper. We thank Certibit Consulting, LLC, Huazhong University of Science and Technology and the SecLab team at Northeastern University for reporting this issue. Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
This commit is contained in:
		
							parent
							
								
									c2d616eaee
								
							
						
					
					
						commit
						79704b8213
					
				
							
								
								
									
										2
									
								
								.github/lexicon.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/lexicon.txt
									
									
									
									
										vendored
									
									
								
							@ -2547,7 +2547,6 @@ vportgetheapstats
 | 
			
		||||
vportinitialiseblocks
 | 
			
		||||
vportisrstartfirststask
 | 
			
		||||
vportraisebasepri
 | 
			
		||||
vportresetprivilege
 | 
			
		||||
vportsetmpuregistersetone
 | 
			
		||||
vportsetuptimerinterrupt
 | 
			
		||||
vportstartfirststask
 | 
			
		||||
@ -2872,7 +2871,6 @@ xperiod
 | 
			
		||||
xportgetcoreid
 | 
			
		||||
xportgetfreeheapsize
 | 
			
		||||
xportinstallinterrupthandler
 | 
			
		||||
xportraiseprivilege
 | 
			
		||||
xportregistercinterrupthandler
 | 
			
		||||
xportregisterdump
 | 
			
		||||
xportstartfirsttask
 | 
			
		||||
 | 
			
		||||
@ -173,36 +173,6 @@
 | 
			
		||||
        #define PRIVILEGED_DATA         __attribute__( ( section( "privileged_data" ) ) )
 | 
			
		||||
        #define FREERTOS_SYSTEM_CALL    __attribute__( ( section( "freertos_system_calls" ) ) )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Calls the port specific code to raise the privilege.
 | 
			
		||||
 *
 | 
			
		||||
 * Sets xRunningPrivileged to pdFALSE if privilege was raised, else sets
 | 
			
		||||
 * it to pdTRUE.
 | 
			
		||||
 */
 | 
			
		||||
        #define xPortRaisePrivilege( xRunningPrivileged )                  \
 | 
			
		||||
    {                                                                      \
 | 
			
		||||
        /* Check whether the processor is already privileged. */           \
 | 
			
		||||
        ( xRunningPrivileged ) = portIS_PRIVILEGED();                      \
 | 
			
		||||
                                                                           \
 | 
			
		||||
        /* If the processor is not already privileged, raise privilege. */ \
 | 
			
		||||
        if( ( xRunningPrivileged ) == pdFALSE )                            \
 | 
			
		||||
        {                                                                  \
 | 
			
		||||
            portRAISE_PRIVILEGE();                                         \
 | 
			
		||||
        }                                                                  \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief If xRunningPrivileged is not pdTRUE, calls the port specific
 | 
			
		||||
 * code to reset the privilege, otherwise does nothing.
 | 
			
		||||
 */
 | 
			
		||||
        #define vPortResetPrivilege( xRunningPrivileged ) \
 | 
			
		||||
    {                                                     \
 | 
			
		||||
        if( ( xRunningPrivileged ) == pdFALSE )           \
 | 
			
		||||
        {                                                 \
 | 
			
		||||
            portRESET_PRIVILEGE();                        \
 | 
			
		||||
        }                                                 \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
 | 
			
		||||
 | 
			
		||||
#else /* portUSING_MPU_WRAPPERS */
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -495,15 +495,26 @@ void vPortEndScheduler( void )
 | 
			
		||||
void vPortEnterCritical( void )
 | 
			
		||||
{
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    BaseType_t xRunningPrivileged;
 | 
			
		||||
    xPortRaisePrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
    if( portIS_PRIVILEGED() == pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        portRAISE_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portDISABLE_INTERRUPTS();
 | 
			
		||||
        uxCriticalNesting++;
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portRESET_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        portDISABLE_INTERRUPTS();
 | 
			
		||||
        uxCriticalNesting++;
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    portDISABLE_INTERRUPTS();
 | 
			
		||||
    uxCriticalNesting++;
 | 
			
		||||
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    vPortResetPrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
@ -511,10 +522,34 @@ void vPortEnterCritical( void )
 | 
			
		||||
void vPortExitCritical( void )
 | 
			
		||||
{
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    BaseType_t xRunningPrivileged;
 | 
			
		||||
    xPortRaisePrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
    if( portIS_PRIVILEGED() == pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        portRAISE_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        configASSERT( uxCriticalNesting );
 | 
			
		||||
        uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
        if( uxCriticalNesting == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            portENABLE_INTERRUPTS();
 | 
			
		||||
        }
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portRESET_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        configASSERT( uxCriticalNesting );
 | 
			
		||||
        uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
        if( uxCriticalNesting == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            portENABLE_INTERRUPTS();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    configASSERT( uxCriticalNesting );
 | 
			
		||||
    uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
@ -522,9 +557,6 @@ void vPortExitCritical( void )
 | 
			
		||||
    {
 | 
			
		||||
        portENABLE_INTERRUPTS();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    vPortResetPrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
@ -549,15 +549,26 @@ void vPortEndScheduler( void )
 | 
			
		||||
void vPortEnterCritical( void )
 | 
			
		||||
{
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    BaseType_t xRunningPrivileged;
 | 
			
		||||
    xPortRaisePrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
    if( portIS_PRIVILEGED() == pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        portRAISE_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portDISABLE_INTERRUPTS();
 | 
			
		||||
        uxCriticalNesting++;
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portRESET_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        portDISABLE_INTERRUPTS();
 | 
			
		||||
        uxCriticalNesting++;
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    portDISABLE_INTERRUPTS();
 | 
			
		||||
    uxCriticalNesting++;
 | 
			
		||||
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    vPortResetPrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
@ -565,10 +576,34 @@ void vPortEnterCritical( void )
 | 
			
		||||
void vPortExitCritical( void )
 | 
			
		||||
{
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    BaseType_t xRunningPrivileged;
 | 
			
		||||
    xPortRaisePrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
    if( portIS_PRIVILEGED() == pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        portRAISE_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        configASSERT( uxCriticalNesting );
 | 
			
		||||
        uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
        if( uxCriticalNesting == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            portENABLE_INTERRUPTS();
 | 
			
		||||
        }
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portRESET_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        configASSERT( uxCriticalNesting );
 | 
			
		||||
        uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
        if( uxCriticalNesting == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            portENABLE_INTERRUPTS();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    configASSERT( uxCriticalNesting );
 | 
			
		||||
    uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
@ -576,9 +611,6 @@ void vPortExitCritical( void )
 | 
			
		||||
    {
 | 
			
		||||
        portENABLE_INTERRUPTS();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    vPortResetPrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
@ -464,13 +464,44 @@ void vPortEndScheduler( void )
 | 
			
		||||
void vPortEnterCritical( void )
 | 
			
		||||
{
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    BaseType_t xRunningPrivileged;
 | 
			
		||||
    xPortRaisePrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
    if( portIS_PRIVILEGED() == pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        portRAISE_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portDISABLE_INTERRUPTS();
 | 
			
		||||
        uxCriticalNesting++;
 | 
			
		||||
        /* This is not the interrupt safe version of the enter critical function so
 | 
			
		||||
         * assert() if it is being called from an interrupt context.  Only API
 | 
			
		||||
         * functions that end in "FromISR" can be used in an interrupt.  Only assert if
 | 
			
		||||
         * the critical nesting count is 1 to protect against recursive calls if the
 | 
			
		||||
         * assert function also uses a critical section. */
 | 
			
		||||
        if( uxCriticalNesting == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
 | 
			
		||||
        }
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portRESET_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        portDISABLE_INTERRUPTS();
 | 
			
		||||
        uxCriticalNesting++;
 | 
			
		||||
        /* This is not the interrupt safe version of the enter critical function so
 | 
			
		||||
         * assert() if it is being called from an interrupt context.  Only API
 | 
			
		||||
         * functions that end in "FromISR" can be used in an interrupt.  Only assert if
 | 
			
		||||
         * the critical nesting count is 1 to protect against recursive calls if the
 | 
			
		||||
         * assert function also uses a critical section. */
 | 
			
		||||
        if( uxCriticalNesting == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    portDISABLE_INTERRUPTS();
 | 
			
		||||
    uxCriticalNesting++;
 | 
			
		||||
 | 
			
		||||
    /* This is not the interrupt safe version of the enter critical function so
 | 
			
		||||
     * assert() if it is being called from an interrupt context.  Only API
 | 
			
		||||
     * functions that end in "FromISR" can be used in an interrupt.  Only assert if
 | 
			
		||||
@ -480,9 +511,6 @@ void vPortEnterCritical( void )
 | 
			
		||||
    {
 | 
			
		||||
        configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    vPortResetPrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
@ -490,21 +518,41 @@ void vPortEnterCritical( void )
 | 
			
		||||
void vPortExitCritical( void )
 | 
			
		||||
{
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    BaseType_t xRunningPrivileged;
 | 
			
		||||
    xPortRaisePrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
    if( portIS_PRIVILEGED() == pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        portRAISE_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        configASSERT( uxCriticalNesting );
 | 
			
		||||
        uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
        if( uxCriticalNesting == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            portENABLE_INTERRUPTS();
 | 
			
		||||
        }
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portRESET_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        configASSERT( uxCriticalNesting );
 | 
			
		||||
        uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
        if( uxCriticalNesting == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            portENABLE_INTERRUPTS();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    configASSERT( uxCriticalNesting );
 | 
			
		||||
 | 
			
		||||
    uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
    if( uxCriticalNesting == 0 )
 | 
			
		||||
    {
 | 
			
		||||
        portENABLE_INTERRUPTS();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    vPortResetPrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
@ -551,15 +551,26 @@ void vPortEndScheduler( void )
 | 
			
		||||
void vPortEnterCritical( void )
 | 
			
		||||
{
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    BaseType_t xRunningPrivileged;
 | 
			
		||||
    xPortRaisePrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
    if( portIS_PRIVILEGED() == pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        portRAISE_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portDISABLE_INTERRUPTS();
 | 
			
		||||
        uxCriticalNesting++;
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portRESET_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        portDISABLE_INTERRUPTS();
 | 
			
		||||
        uxCriticalNesting++;
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    portDISABLE_INTERRUPTS();
 | 
			
		||||
    uxCriticalNesting++;
 | 
			
		||||
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    vPortResetPrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
@ -567,10 +578,34 @@ void vPortEnterCritical( void )
 | 
			
		||||
void vPortExitCritical( void )
 | 
			
		||||
{
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    BaseType_t xRunningPrivileged;
 | 
			
		||||
    xPortRaisePrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
    if( portIS_PRIVILEGED() == pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        portRAISE_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        configASSERT( uxCriticalNesting );
 | 
			
		||||
        uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
        if( uxCriticalNesting == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            portENABLE_INTERRUPTS();
 | 
			
		||||
        }
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
 | 
			
		||||
        portRESET_PRIVILEGE();
 | 
			
		||||
        portMEMORY_BARRIER();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        configASSERT( uxCriticalNesting );
 | 
			
		||||
        uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
        if( uxCriticalNesting == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            portENABLE_INTERRUPTS();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    configASSERT( uxCriticalNesting );
 | 
			
		||||
    uxCriticalNesting--;
 | 
			
		||||
 | 
			
		||||
@ -578,9 +613,6 @@ void vPortExitCritical( void )
 | 
			
		||||
    {
 | 
			
		||||
        portENABLE_INTERRUPTS();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
 | 
			
		||||
    vPortResetPrivilege( xRunningPrivileged );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user