Add option to disable unprivileged critical sections
This commit introduces a new config
configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS which enables developers to
prevent critical sections from unprivileged tasks. It defaults to 1 for
backward compatibility. Application should set it to 0 to disable
critical sections from unprivileged tasks.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c
index 1e26c77..f76a851 100644
--- a/portable/GCC/ARM_CM3_MPU/port.c
+++ b/portable/GCC/ARM_CM3_MPU/port.c
@@ -52,6 +52,11 @@
#define portNVIC_SYSTICK_CLK ( 0 )
#endif
+#ifndef configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS
+ #warning "configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not defined. We recommend defining it to 0 in FreeRTOSConfig.h for better security."
+ #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
+#endif
+
/* Constants required to access and manipulate the NVIC. */
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
@@ -162,12 +167,20 @@
/**
* @brief Enter critical section.
*/
-void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
+#else
+ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION;
+#endif
/**
* @brief Exit from critical section.
*/
-void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
+#else
+ void vPortExitCritical( void ) PRIVILEGED_FUNCTION;
+#endif
/*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting
@@ -480,20 +493,26 @@
void vPortEnterCritical( void )
{
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
BaseType_t xRunningPrivileged;
xPortRaisePrivilege( xRunningPrivileged );
+#endif
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
vPortResetPrivilege( xRunningPrivileged );
+#endif
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
BaseType_t xRunningPrivileged;
xPortRaisePrivilege( xRunningPrivileged );
+#endif
configASSERT( uxCriticalNesting );
uxCriticalNesting--;
@@ -503,7 +522,9 @@
portENABLE_INTERRUPTS();
}
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
vPortResetPrivilege( xRunningPrivileged );
+#endif
}
/*-----------------------------------------------------------*/
diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c
index d70366a..9cf9c44 100644
--- a/portable/GCC/ARM_CM4_MPU/port.c
+++ b/portable/GCC/ARM_CM4_MPU/port.c
@@ -56,6 +56,11 @@
#define portNVIC_SYSTICK_CLK ( 0 )
#endif
+#ifndef configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS
+ #warning "configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not defined. We recommend defining it to 0 in FreeRTOSConfig.h for better security."
+ #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
+#endif
+
/* Constants required to access and manipulate the NVIC. */
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
@@ -175,12 +180,20 @@
/**
* @brief Enter critical section.
*/
-void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
+#else
+ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION;
+#endif
/**
* @brief Exit from critical section.
*/
-void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
+#else
+ void vPortExitCritical( void ) PRIVILEGED_FUNCTION;
+#endif
/*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting
@@ -516,20 +529,26 @@
void vPortEnterCritical( void )
{
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
BaseType_t xRunningPrivileged;
xPortRaisePrivilege( xRunningPrivileged );
+#endif
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
vPortResetPrivilege( xRunningPrivileged );
+#endif
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
BaseType_t xRunningPrivileged;
xPortRaisePrivilege( xRunningPrivileged );
+#endif
configASSERT( uxCriticalNesting );
uxCriticalNesting--;
@@ -539,7 +558,9 @@
portENABLE_INTERRUPTS();
}
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
vPortResetPrivilege( xRunningPrivileged );
+#endif
}
/*-----------------------------------------------------------*/
diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c
index 34e4bad..5e8c723 100644
--- a/portable/IAR/ARM_CM4F_MPU/port.c
+++ b/portable/IAR/ARM_CM4F_MPU/port.c
@@ -63,6 +63,11 @@
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
#endif
+#ifndef configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS
+ #warning "configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not defined. We recommend defining it to 0 in FreeRTOSConfig.h for better security."
+ #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
+#endif
+
/* Constants required to manipulate the core. Registers first... */
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
@@ -188,12 +193,20 @@
/**
* @brief Enter critical section.
*/
-void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
+#else
+ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION;
+#endif
/**
* @brief Exit from critical section.
*/
-void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
+#else
+ void vPortExitCritical( void ) PRIVILEGED_FUNCTION;
+#endif
/*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting
@@ -444,8 +457,10 @@
void vPortEnterCritical( void )
{
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
BaseType_t xRunningPrivileged;
xPortRaisePrivilege( xRunningPrivileged );
+#endif
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
@@ -460,14 +475,18 @@
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
}
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
vPortResetPrivilege( xRunningPrivileged );
+#endif
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
BaseType_t xRunningPrivileged;
xPortRaisePrivilege( xRunningPrivileged );
+#endif
configASSERT( uxCriticalNesting );
@@ -478,7 +497,9 @@
portENABLE_INTERRUPTS();
}
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
vPortResetPrivilege( xRunningPrivileged );
+#endif
}
/*-----------------------------------------------------------*/
diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c
index f61b854..4d3c4a4 100644
--- a/portable/RVDS/ARM_CM4_MPU/port.c
+++ b/portable/RVDS/ARM_CM4_MPU/port.c
@@ -45,6 +45,11 @@
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+#ifndef configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS
+ #warning "configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not defined. We recommend defining it to 0 in FreeRTOSConfig.h for better security."
+ #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
+#endif
+
/* Constants required to access and manipulate the NVIC. */
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
@@ -189,12 +194,20 @@
/**
* @brief Enter critical section.
*/
-void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ void vPortEnterCritical( void ) FREERTOS_SYSTEM_CALL;
+#else
+ void vPortEnterCritical( void ) PRIVILEGED_FUNCTION;
+#endif
/**
* @brief Exit from critical section.
*/
-void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
+ void vPortExitCritical( void ) FREERTOS_SYSTEM_CALL;
+#else
+ void vPortExitCritical( void ) PRIVILEGED_FUNCTION;
+#endif
/*-----------------------------------------------------------*/
/*
@@ -519,20 +532,26 @@
void vPortEnterCritical( void )
{
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
BaseType_t xRunningPrivileged;
xPortRaisePrivilege( xRunningPrivileged );
+#endif
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
vPortResetPrivilege( xRunningPrivileged );
+#endif
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
BaseType_t xRunningPrivileged;
xPortRaisePrivilege( xRunningPrivileged );
+#endif
configASSERT( uxCriticalNesting );
uxCriticalNesting--;
@@ -542,7 +561,9 @@
portENABLE_INTERRUPTS();
}
+#if( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 )
vPortResetPrivilege( xRunningPrivileged );
+#endif
}
/*-----------------------------------------------------------*/