This PR adds Access Control to kernel objects on a per task basis to MPU
ports. The following needs to be defined in the `FreeRTOSConfig.h` to
enable this feature:
```c
#define configUSE_MPU_WRAPPERS_V1 0
#define configENABLE_ACCESS_CONTROL_LIST 1
```
This PR adds the following new APIs:
```c
void vGrantAccessToTask( TaskHandle_t xTask,
TaskHandle_t xTaskToGrantAccess );
void vRevokeAccessToTask( TaskHandle_t xTask,
TaskHandle_t xTaskToRevokeAccess );
void vGrantAccessToSemaphore( TaskHandle_t xTask,
SemaphoreHandle_t xSemaphoreToGrantAccess );
void vRevokeAccessToSemaphore( TaskHandle_t xTask,
SemaphoreHandle_t xSemaphoreToRevokeAccess );
void vGrantAccessToQueue( TaskHandle_t xTask,
QueueHandle_t xQueueToGrantAccess );
void vRevokeAccessToQueue( TaskHandle_t xTask,
QueueHandle_t xQueueToRevokeAccess );
void vGrantAccessToQueueSet( TaskHandle_t xTask,
QueueSetHandle_t xQueueSetToGrantAccess );
void vRevokeAccessToQueueSet( TaskHandle_t xTask,
QueueSetHandle_t xQueueSetToRevokeAccess );
void vGrantAccessToEventGroup( TaskHandle_t xTask,
EventGroupHandle_t xEventGroupToGrantAccess );
void vRevokeAccessToEventGroup( TaskHandle_t xTask,
EventGroupHandle_t xEventGroupToRevokeAccess );
void vGrantAccessToStreamBuffer( TaskHandle_t xTask,
StreamBufferHandle_t xStreamBufferToGrantAccess );
void vRevokeAccessToStreamBuffer( TaskHandle_t xTask,
StreamBufferHandle_t xStreamBufferToRevokeAccess );
void vGrantAccessToMessageBuffer( TaskHandle_t xTask,
MessageBufferHandle_t xMessageBufferToGrantAccess );
void vRevokeAccessToMessageBuffer( TaskHandle_t xTask,
MessageBufferHandle_t xMessageBufferToRevokeAccess );
void vGrantAccessToTimer( TaskHandle_t xTask,
TimerHandle_t xTimerToGrantAccess );
void vRevokeAccessToTimer( TaskHandle_t xTask,
TimerHandle_t xTimerToRevokeAccess );
```
An unprivileged task by default has access to itself only and no other
kernel object. The application writer needs to explicitly grant an
unprivileged task access to all the kernel objects it needs. The best
place to do that is before starting the scheduler when all the kernel
objects are created.
For example, let's say an unprivileged tasks needs access to a queue and
an event group, the application writer needs to do the following:
```c
vGrantAccessToQueue( xUnprivilegedTaskHandle, xQueue );
vGrantAccessToEventGroup( xUnprivilegedTaskHandle, xEventGroup );
```
The application writer MUST revoke all the accesses before deleting a
task. Failing to do so will result in undefined behavior. In the above
example, the application writer needs to make the following 2 calls
before deleting the task:
```c
vRevokeAccessToQueue( xUnprivilegedTaskHandle, xQueue );
vRevokeAccessToEventGroup( xUnprivilegedTaskHandle, xEventGroup );
```
* Use new version of CI-CD Actions
* Use cSpell spell check, and use ubuntu-20.04 for formatting check
* Format and spell check all files in the portable directory
* Remove the https:// from #errors and #warnings as uncrustify attempts to change it to /*
* Use checkout@v3 instead of checkout@v2 on all jobs
---------
Memory Protection Unit (MPU) Enhancements
This commit introduces a new MPU wrapper that places additional
restrictions on unprivileged tasks. The following is the list of changes
introduced with the new MPU wrapper:
1. Opaque and indirectly verifiable integers for kernel object handles:
All the kernel object handles (for example, queue handles) are now
opaque integers. Previously object handles were raw pointers.
2. Saving the task context in Task Control Block (TCB): When a task is
swapped out by the scheduler, the task's context is now saved in its
TCB. Previously the task's context was saved on its stack.
3. Execute system calls on a separate privileged only stack: FreeRTOS
system calls, which execute with elevated privilege, now use a
separate privileged only stack. Previously system calls used the
calling task's stack. The application writer can control the size of
the system call stack using new configSYSTEM_CALL_STACK_SIZE config
macro.
4. Memory bounds checks: FreeRTOS system calls which accept a pointer
and de-reference it, now verify that the calling task has required
permissions to access the memory location referenced by the pointer.
5. System call restrictions: The following system calls are no longer
available to unprivileged tasks:
- vQueueDelete
- xQueueCreateMutex
- xQueueCreateMutexStatic
- xQueueCreateCountingSemaphore
- xQueueCreateCountingSemaphoreStatic
- xQueueGenericCreate
- xQueueGenericCreateStatic
- xQueueCreateSet
- xQueueRemoveFromSet
- xQueueGenericReset
- xTaskCreate
- xTaskCreateStatic
- vTaskDelete
- vTaskPrioritySet
- vTaskSuspendAll
- xTaskResumeAll
- xTaskGetHandle
- xTaskCallApplicationTaskHook
- vTaskList
- vTaskGetRunTimeStats
- xTaskCatchUpTicks
- xEventGroupCreate
- xEventGroupCreateStatic
- vEventGroupDelete
- xStreamBufferGenericCreate
- xStreamBufferGenericCreateStatic
- vStreamBufferDelete
- xStreamBufferReset
Also, an unprivileged task can no longer use vTaskSuspend to suspend
any task other than itself.
We thank the following people for their inputs in these enhancements:
- David Reiss of Meta Platforms, Inc.
- Lan Luo, Xinhui Shao, Yumeng Wei, Zixia Liu, Huaiyu Yan and Zhen Ling
of School of Computer Science and Engineering, Southeast University,
China.
- Xinwen Fu of Department of Computer Science, University of
Massachusetts Lowell, USA.
- Yuequi Chen, Zicheng Wang, Minghao Lin of University of Colorado
Boulder, USA.
* Remove __NVIC_PRIO_BITS and configPRIO_BITS check in CM3, CM4 and ARMv8.
* Add hardware not implemented bits check. These bits should be zero.
---------
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
Adjust assertions related to the CMSIS __NVIC_PRIO_BITS and FreeRTOS
configPRIO_BITS configuration macros such that these macros specify the
minimum number of implemented priority bits supported by a config
build rather than the exact number of implemented priority bits.
Related to Qemu issue #1122
FreeRTOS-Kernel/portable/GCC/ARM_CM4F/port.c:399:41: error: conversion from 'uint32_t' {aka 'long unsigned int'} to 'uint8_t' {aka 'unsigned char'} may change value [-Werror=conversion]
Signed-off-by: Vo Trung Chi <chi.votrung@vn.bosch.com>
* Interrupt priority assert improvements for CM3/4/7
In the ARM_CM3, ARM_CM4, and ARM_CM7 ports, change the assertion that
`configMAX_SYSCALL_INTERRUPT_PRIORITY` is nonzero to account for the
number of priority bits implemented by the hardware.
Change these ports to also use the lowest priority for PendSV and
SysTick, ignoring `configKERNEL_INTERRUPT_PRIORITY`.
* Remove not needed configKERNEL_INTERRUPT_PRIORITY define
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
---------
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
* Adding in ability to support a library for freertos_config and a custom freertos_kernel_port (#558)
* Using single name definition for libraries everywhere. (#558)
* Supporting backwards compatibility with FREERTOS_CONFIG_FILE_DIRECTORY (#571)
* Removing compiler warnings for GNU and Clang. (#571)
* Added in documentation on how to consume from a main project. Added default PORT selection for native POSIX and MINGW platforms.
* Only adding freertos_config if it exists. Removing auto generation of it from a FREERTOS_CONFIG_FILE_DIRECTORY.
* Fixing clang and gnu compiler warnings.
* Adding in project information and how to compile for GNU/clang
* Fixing compiler issue with unused variable - no need to declare variable.
* Adding in compile warnings for linux builds that kernel is okay with using.
* Fixing more extra-semi-stmt clang warnings.
* Moving definition of hooks into header files if features are enabled.
* Fixing formatting with uncrustify.
* Fixing merge conflicts with main merge.
* Fixing compiler errors due to merge issues and formatting.
* Fixing Line feeds.
* Adding 'portNORETURN' into portmacros.h. Other Updates based on PR request
* Further clean-up of clang and clang-tidy issues.
* Removing compiler specific pragmas from common c files.
* Fixing missing lexicon entry and uncrustify formatting changes.
* Resolving merge issue multiple defnitions of proto for prvIdleTask
* Fixing formatting issues that are not covered by uncrustify. Use clang-tidy instead if you want this level of control.
* More uncrustify formatting issues.
* Fixing extra bracket in #if statement.
---------
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
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>
ARMv7-M allows overlapping MPU regions. When 2 MPU regions overlap, the
MPU configuration of the higher numbered MPU region is applied. For
example, if a memory area is covered by 2 MPU regions 0 and 1, the
memory permissions for MPU region 1 are applied.
We use 5 MPU regions for kernel code and kernel data protections and
leave the remaining for the application writer. We were using lowest
numbered MPU regions (0-4) for kernel protections and leaving the
remaining for the application writer. The application writer could
configure those higher numbered MPU regions to override kernel
protections.
This commit changes the code to use highest numbered MPU regions for
kernel protections and leave the remaining for the application writer.
This ensures that the application writer cannot override kernel
protections.
We thank the SecLab team at Northeastern University for reporting this
issue.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
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>
* Style: make freertos.org = FreeRTOS.org also add https
* Style: Fix freertos into FreeRTOS
* Style: Fix freertos into FreeRTOS
Co-authored-by: Alfred Gedeon <gedeonag@amazon.com>
* Style: Change FreeRTOS websites in comments
* Style: Change freertos to FreeRTOS in comments
* Style: Remove broken link
Co-authored-by: Alfred Gedeon <gedeonag@amazon.com>
The reason for the change is that the register is called System Handler
Priority Register 3 (SHPR3).
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
When Link Time Optimization (LTO) is enabled, some of the LDR
instructions result in out of range access. The reason is that the
default generated literal pool is too far and not within the permissible
range of 4K.
This commit adds LTORG assembly instructions at required places to
ensure that access to literals remain in the permissible range of 4K.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Enabling Link Time Optimization (LTO) causes some of the functions used
in assembly to be incorrectly stripped off, resulting in linker error.
To avoid this, these functions are marked with portDONT_DISCARD macro,
definition of which is port specific. This commit adds the definition
of portDONT_DISCARD for ARMv7-M ports.
Signed-off-by: Gaurav Aggarwal
Problem Description
-------------------
The current flash organization in ARMv7-M MPU ports looks as follows:
__FLASH_segment_start__ ------->+-----------+<----- __FLASH_segment_start__
| Vector |
| Table |
| + |
| Kernel |
| Code |
+-----------+<----- __privileged_functions_end__
| |
| |
| |
| Other |
| Code |
| |
| |
| |
__FLASH_segment_end__ ------>+-----------+
The FreeRTOS kernel sets up the following MPU regions:
* Unprivileged Code - __FLASH_segment_start__ to __FLASH_segment_end__.
* Privileged Code - __FLASH_segment_start__ to __privileged_functions_end__.
The above setup assumes that the FreeRTOS kernel code
(i.e. privileged_functions) is placed at the beginning of the flash and,
therefore, uses __FLASH_segment_start__ as the starting location of the
privileged code. This prevents a user from placing the FreeRTOS kernel
code outside of flash (say to an external RAM) and still have vector
table at the beginning of flash (which is many times a hardware
requirement).
Solution
--------
This commit addresses the above limitation by using a new variable
__privileged_functions_start__ as the starting location of the
privileged code. This enables users to place the FreeRTOS kernel code
wherever they choose.
The FreeRTOS kernel now sets up the following MPU regions:
* Unprivileged Code - __FLASH_segment_start__ to __FLASH_segment_end__.
* Privileged Code - __privileged_functions_start__ to __privileged_functions_end__.
As a result, a user can now place the kernel code to an external RAM. A
possible organization is:
Flash External RAM
+------------+ +-----------+<------ __privileged_functions_start__
| Vector | | |
| Table | | |
| | | |
__FLASH_segment_start__ ----->+------------+ | Kernel |
| | | Code |
| | | |
| | | |
| | | |
| Other | | |
| Code | +-----------+<------ __privileged_functions_end__
| |
| |
| |
__FLASH_segment_end__ ----->+------------+
Note that the above configuration places the vector table in an unmapped
region. This is okay because we enable the background region, and so the
vector table will still be accessible to the privileged code and not
accessible to the unprivileged code (vector table is only needed by the
privileged code).
Backward Compatibility
----------------------
The FreeRTOS kernel code now uses a new variable, namely
__privileged_functions_start__, which needs to be exported from linker
script to indicate the starting location of the privileged code. All of
our existing demos already export this variable and therefore, they will
continue to work.
If a user has created a project which does not export this variable,
they will get a linker error for unresolved symbol
__privileged_functions_start__. They need to export a variable
__privileged_functions_start__ with the value equal to
__FLASH_segment_start__.
Issue
-----
https://sourceforge.net/p/freertos/feature-requests/56/
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>