mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 13:01:57 -04:00
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…
Reference in a new issue