mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-08 20:55:14 -05:00
Add in Access Control List support to the port
This commit is contained in:
parent
d8b08270d0
commit
80d09879d1
2 changed files with 143 additions and 111 deletions
|
|
@ -39,6 +39,7 @@
|
|||
/* Scheduler includes. */
|
||||
#include "FreeRTOSConfig.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "portmacro_asm.h"
|
||||
#include "portmacro.h"
|
||||
#include "task.h"
|
||||
#include "mpu_syscall_numbers.h"
|
||||
|
|
@ -589,73 +590,16 @@ BaseType_t xPortIsAuthorizedToAccessBuffer(
|
|||
return xAccessGranted;
|
||||
}
|
||||
|
||||
#if( configENABLE_ACCESS_CONTROL_LIST == 1 )
|
||||
|
||||
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject )
|
||||
/* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
|
||||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings;
|
||||
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
ulAccessControlListEntryIndex =
|
||||
( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
|
||||
ulAccessControlListEntryBit =
|
||||
( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) ==
|
||||
portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &
|
||||
( 1U << ulAccessControlListEntryBit ) ) != 0 )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xAccessGranted;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject
|
||||
) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
( void ) lInternalIndexOfKernelObject;
|
||||
|
||||
/* If Access Control List feature is not used, all the tasks have
|
||||
* access to all the kernel objects. */
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/** @brief Determine if the FreeRTOS Task was created as a privileged task
|
||||
*
|
||||
* @return BaseType_t pdTRUE if the task's ulTaskFlags mark it as privileged.
|
||||
* pdFALSE if the task was not created as a privileged task.
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
* @ingroup Task Context
|
||||
*
|
||||
* @return pdTRUE if the Task was created as a privileged task.
|
||||
* pdFALSE if the task was not created as a privileged task.
|
||||
*
|
||||
*/
|
||||
BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
|
|
@ -672,6 +616,122 @@ BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */
|
|||
|
||||
return xTaskIsPrivileged;
|
||||
}
|
||||
|
||||
/** @brief Start the FreeRTOS-Kernel's control of Tasks by starting the System Tick
|
||||
* Interrupt.
|
||||
*
|
||||
* @ingroup Scheduler
|
||||
* @return BaseType_t This function is not meant to be returned from.
|
||||
* If it does return it returns pdFALSE to mark that the scheduler could not be started.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. */
|
||||
configSETUP_TICK_INTERRUPT();
|
||||
|
||||
/* Reset the critical section nesting count read to execute the first task. */
|
||||
ulCriticalNesting = 0UL;
|
||||
|
||||
/* Configure the regions in the MPU that are common to all tasks. */
|
||||
prvSetupDefaultMPU();
|
||||
|
||||
xSchedulerRunning = pdTRUE;
|
||||
|
||||
/* Load the context of the first task, starting the FreeRTOS-Scheduler's control. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
||||
* a non-privileged mode or the binary point register was not set to its lowest
|
||||
* possible value. prvTaskExitError() is referenced to prevent a compiler
|
||||
* warning about it being defined but not referenced in the case that the user
|
||||
* defines their own exit address. */
|
||||
( void ) prvTaskExitError();
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_ACCESS_CONTROL_LIST == 1 )
|
||||
|
||||
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
|
||||
BaseType_t xAccessGranted = pdFALSE;
|
||||
const xMPU_SETTINGS * xTaskMpuSettings;
|
||||
|
||||
if( xSchedulerRunning == pdFALSE )
|
||||
{
|
||||
/* Grant access to all the kernel objects before the scheduler
|
||||
* is started. It is necessary because there is no task running
|
||||
* yet and therefore, we cannot use the permissions of any
|
||||
* task. */
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
|
||||
|
||||
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
|
||||
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
|
||||
|
||||
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
|
||||
{
|
||||
xAccessGranted = pdTRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xAccessGranted;
|
||||
}
|
||||
|
||||
|
||||
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
|
||||
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
|
||||
xMPU_SETTINGS * xTaskMpuSettings;
|
||||
|
||||
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
|
||||
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
|
||||
|
||||
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
|
||||
|
||||
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
|
||||
}
|
||||
|
||||
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
|
||||
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
|
||||
xMPU_SETTINGS * xTaskMpuSettings;
|
||||
|
||||
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
|
||||
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
|
||||
|
||||
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
|
||||
|
||||
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject
|
||||
) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
( void ) lInternalIndexOfKernelObject;
|
||||
|
||||
/* If Access Control List feature is not used, all the tasks have
|
||||
* access to all the kernel objects. */
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/** @brief Function that is used as the default Link Register address for a new Task
|
||||
|
|
@ -698,54 +758,6 @@ void prvTaskExitError( void )
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/** @brief Start the FreeRTOS-Kernel's control of Tasks by starting the System Tick
|
||||
* Interrupt.
|
||||
*
|
||||
* @ingroup Scheduler
|
||||
* @return BaseType_t This function is not meant to be returned from.
|
||||
* If it does return it returns pdFALSE to mark that the scheduler could not be started.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
#if defined( __ARMCC_VERSION )
|
||||
/* Declaration when these variable are defined in code instead of being
|
||||
* exported from linker scripts. */
|
||||
/* Sections used for Privileged Stacks to zero them out before starting tasks */
|
||||
extern uint32_t * __privileged_stacks_start__;
|
||||
extern uint32_t * __privileged_stacks_end__;
|
||||
#else /* if defined( __ARMCC_VERSION ) */
|
||||
/* Declaration when these variable are exported from linker scripts. */
|
||||
/* Sections used for Privileged Stacks to zero them out before starting tasks */
|
||||
/*
|
||||
extern uint32_t __privileged_stacks_start__[];
|
||||
extern uint32_t __privileged_stacks_end__[];
|
||||
*/
|
||||
#endif /* if defined( __ARMCC_VERSION ) */
|
||||
|
||||
/* Start the timer that generates the tick ISR. */
|
||||
configSETUP_TICK_INTERRUPT();
|
||||
|
||||
/* Reset the critical section nesting count read to execute the first task. */
|
||||
ulCriticalNesting = 0UL;
|
||||
|
||||
/* Configure the regions in the MPU that are common to all tasks. */
|
||||
prvSetupDefaultMPU();
|
||||
|
||||
xSchedulerRunning = pdTRUE;
|
||||
|
||||
/* Load the context of the first task, starting the FreeRTOS-Scheduler's control. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
||||
* a non-privileged mode or the binary point register was not set to its lowest
|
||||
* possible value. prvTaskExitError() is referenced to prevent a compiler
|
||||
* warning about it being defined but not referenced in the case that the user
|
||||
* defines their own exit address. */
|
||||
( void ) prvTaskExitError();
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/** @brief Function meant to end the FreeRTOS Scheduler, not implemented on this port.
|
||||
* @ingroup Scheduler
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* FreeRTOS Kernel V11.0.1
|
||||
* Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
|
|
@ -69,6 +69,15 @@ extern "C" {
|
|||
#error This Port is only usable with configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY set to 1
|
||||
#endif /* ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY != 1 ) */
|
||||
|
||||
#ifndef configENABLE_ACCESS_CONTROL_LIST
|
||||
#define configENABLE_ACCESS_CONTROL_LIST 0
|
||||
#elif( configENABLE_ACCESS_CONTROL_LIST == 1 )
|
||||
#ifndef configPROTECTED_KERNEL_OBJECT_POOL_SIZE
|
||||
#error "Set configPROTECTED_KERNEL_OBJECT_POOL_SIZE to at least the number " \
|
||||
"of FreeRTOS-Kernel Objects to be created"
|
||||
#endif /* configPROTECTED_KERNEL_OBJECT_POOL_SIZE */
|
||||
#endif /* configENABLE_ACCESS_CONTROL_LIST */
|
||||
|
||||
/** @brief The size in Bytes that the Privileged System Call Stack should be.
|
||||
*
|
||||
* @ingroup MPU Privilege
|
||||
|
|
@ -537,8 +546,15 @@ UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap );
|
|||
* padded. */
|
||||
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||
|
||||
/** @brief Size of the System Call Buffer in the TCB
|
||||
* @ingroup Task Context
|
||||
*/
|
||||
|
||||
#define portSYSTEM_CALL_STACK_SIZE configSYSTEM_CALL_STACK_SIZE
|
||||
|
||||
/* Size of an Access Control List (ACL) entry in bits. */
|
||||
#define portACL_ENTRY_SIZE_BITS ( 32U )
|
||||
|
||||
/** @brief Structure to hold the MPU Register Values
|
||||
* @struct xMPU_REGION_REGISTERS
|
||||
*
|
||||
|
|
@ -652,6 +668,10 @@ typedef struct MPU_SETTINGS
|
|||
* @ingroup Port Privilege
|
||||
*/
|
||||
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
|
||||
|
||||
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
|
||||
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
|
||||
#endif
|
||||
} xMPU_SETTINGS;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue