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

 }

 /*-----------------------------------------------------------*/