Disallow unprivileged critical sections with MPU wrappers v2 (#1427)
When using MPU wrappers version 2 (configUSE_MPU_WRAPPERS_V1 == 0),
portRAISE_PRIVILEGE() is a no-op because the portSVC_RAISE_PRIVILEGE
handler is compiled only for MPU wrappers version 1. As a result, an
unprivileged task that calls taskENTER_CRITICAL() does not actually raise
its privilege, so the subsequent BASEPRI write is ignored by the hardware
and the critical section silently fails to mask interrupts. This produces
latent, hard-to-debug faults.
configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is therefore not supported with
MPU wrappers version 2. In the ARMv7-M MPU ports:
- When the option is left undefined under v2, default it to 0 instead of 1
so the dangerous default configuration is safe.
- When the option is explicitly set to 1 under v2, raise a compile-time
#error so the unsupported configuration is rejected loudly rather than
failing silently at run time.
Behaviour for MPU wrappers version 1 is unchanged.
diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c
index 8c4dd78..c8d3439 100644
--- a/portable/GCC/ARM_CM3_MPU/port.c
+++ b/portable/GCC/ARM_CM3_MPU/port.c
@@ -55,9 +55,19 @@
#define portNVIC_SYSTICK_CLK ( 0 )
#endif
+/* Unprivileged critical sections are not supported when using MPU wrappers
+ * version 2. Default the option to 0 and reject an explicit value of 1. */
#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
+ #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
+ #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0
+ #else
+ #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
+#else
+ #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) )
+ #error configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not supported with MPU wrappers version 2 ( configUSE_MPU_WRAPPERS_V1 == 0 ).
+ #endif
#endif
/* Prototype of all Interrupt Service Routines (ISRs). */
diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c
index 79f5e76..5a35271 100644
--- a/portable/GCC/ARM_CM4_MPU/port.c
+++ b/portable/GCC/ARM_CM4_MPU/port.c
@@ -59,9 +59,19 @@
#define portNVIC_SYSTICK_CLK ( 0 )
#endif
+/* Unprivileged critical sections are not supported when using MPU wrappers
+ * version 2. Default the option to 0 and reject an explicit value of 1. */
#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
+ #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
+ #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0
+ #else
+ #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
+#else
+ #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) )
+ #error configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not supported with MPU wrappers version 2 ( configUSE_MPU_WRAPPERS_V1 == 0 ).
+ #endif
#endif
/* Prototype of all Interrupt Service Routines (ISRs). */
diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c
index 720138f..0441e0f 100644
--- a/portable/IAR/ARM_CM4F_MPU/port.c
+++ b/portable/IAR/ARM_CM4F_MPU/port.c
@@ -66,9 +66,19 @@
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
#endif
+/* Unprivileged critical sections are not supported when using MPU wrappers
+ * version 2. Default the option to 0 and reject an explicit value of 1. */
#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
+ #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
+ #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0
+ #else
+ #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
+#else
+ #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) )
+ #error configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not supported with MPU wrappers version 2 ( configUSE_MPU_WRAPPERS_V1 == 0 ).
+ #endif
#endif
/* Prototype of all Interrupt Service Routines (ISRs). */
diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c
index 450b862..8620325 100644
--- a/portable/RVDS/ARM_CM4_MPU/port.c
+++ b/portable/RVDS/ARM_CM4_MPU/port.c
@@ -48,9 +48,19 @@
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+/* Unprivileged critical sections are not supported when using MPU wrappers
+ * version 2. Default the option to 0 and reject an explicit value of 1. */
#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
+ #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
+ #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0
+ #else
+ #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
+#else
+ #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) )
+ #error configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is not supported with MPU wrappers version 2 ( configUSE_MPU_WRAPPERS_V1 == 0 ).
+ #endif
#endif
/* Prototype of all Interrupt Service Routines (ISRs). */