Refactoring xPortIsAuthorizedToAccessBuffer

This commit is contained in:
Soren Ptak 2023-12-29 11:18:27 -05:00
parent a1191243f9
commit 43946db07b

View file

@ -499,97 +499,114 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void )
prvMpuEnable(); prvMpuEnable();
} }
/*---------------------------------------------------------------------------*/ /* ------------------------------------------------------------------------- */
/** @brief Determine if a FreeRTOS Task has been granted access to a memory region /** @brief Determine if a FreeRTOS Task has been granted access to a memory region
* *
* @param pvBuffer Base address of the memory region access is being requested. * @param xTaskMPURegion Pointer to a single set of MPU region registers.
* @param ulBufferLength The length of the memory region that access is being requested. * @param ulRegionStart Base address of the memory region access is being requested.
* @param ulRegionLength The length of the memory region that access is being requested.
* @param ulAccessRequested The type of access being requested, either read or write. * @param ulAccessRequested The type of access being requested, either read or write.
* @return BaseType_t pdTRUE if the task can access the region, pdFALSE otherwise * @return BaseType_t pdTRUE if the task can access the region, pdFALSE otherwise
* *
* @ingroup Task Context * @ingroup Task Context
* @ingroup MPU Control * @ingroup MPU Control
*/ */
BaseType_t xPortIsAuthorizedToAccessBuffer( PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion(
const void * pvBuffer, const xMPU_REGION_REGISTERS * xTaskMPURegion,
uint32_t ulBufferLength, const uint32_t ulRegionStart,
uint32_t ulAccessRequested const uint32_t ulRegionLength,
) /* PRIVILEGED_FUNCTION */ const uint32_t ulAccessRequested )
{ {
volatile uint32_t i, ulBufferStartAddress, ulBufferEndAddress; BaseType_t xAccessGranted;
BaseType_t xAccessGranted = pdFALSE; uint32_t ulRegionEnd = ulRegionStart + ulRegionLength;
/* Convert the MPU Region Size value to the actual size */
uint32_t ulTaskRegionLength = 1 << ( ( xTaskMPURegion->ulRegionSize >> 1 ) + 1U );
// uint32_t ulTaskRegionLength = 2 << ( xTaskMPURegion->ulRegionSize >> 1 );
uint32_t ulTaskRegionEnd = xTaskMPURegion->ulRegionBaseAddress + ulTaskRegionLength;
if( ( ulRegionStart >= xTaskMPURegion->ulRegionBaseAddress )
&& ( ulRegionEnd <= ulTaskRegionEnd ) )
{
/* Unprivileged read is MPU Ctrl Access Bit Value bX1X */
if( ( tskMPU_READ_PERMISSION == ulAccessRequested ) &&
( ( portMPU_PRIV_RW_USER_RO_NOEXEC )
& xTaskMPURegion->ulRegionAttribute ) )
{
xAccessGranted = pdTRUE;
}
/* Unprivileged Write is MPU Ctrl Access Bit Value b011 */
else if( ( tskMPU_WRITE_PERMISSION & ulAccessRequested ) &&
( portMPU_PRIV_RW_USER_RW_NOEXEC ==
( portMPU_PRIV_RW_USER_RW_NOEXEC & xTaskMPURegion->ulRegionAttribute ) ) )
{
xAccessGranted = pdTRUE;
}
else
{
xAccessGranted = pdFALSE;
}
}
else
{
xAccessGranted = pdFALSE;
}
return xAccessGranted;
}
/* ------------------------------------------------------------------------- */
BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
uint32_t ulBufferLength,
uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */
{
BaseType_t xAccessGranted;
/* Calling task's MPU settings. */
xMPU_SETTINGS * xTaskMPUSettings = NULL;
xMPU_REGION_REGISTERS * xTaskMPURegion = NULL;
if( pdFALSE == xSchedulerRunning ) if( pdFALSE == xSchedulerRunning )
{ {
/* Before the scheduler starts an unknown task will be pxCurrentTCB */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else else
{ {
/* Calling task's MPU settings. */ xTaskMPUSettings = xTaskGetMPUSettings( NULL );
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL );
uint32_t regionEndAddress = 0U; if( NULL == xTaskMPUSettings )
uint32_t regionLength = 0U;
uint32_t regionStartAddress = 0u;
if( portTASK_IS_PRIVILEGED_FLAG ==
( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) )
{ {
xAccessGranted = pdFALSE;
}
else if( xTaskMPUSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG )
{
/* If a task is privileged it is assumed that it can access the buffer */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else else
{ {
/* Protect against buffer overflow range check */ uint32_t ulRegionIndex = 0x0UL;
if( pdFALSE == do
( ( uint32_t ) pvBuffer >
( ( ( uint32_t ) 0 ) - ( uint32_t ) 1U ) - ulBufferLength - 1UL ) )
{ {
ulBufferStartAddress = ( uint32_t ) pvBuffer; xTaskMPURegion = &( xTaskMPUSettings->xRegion[ ulRegionIndex++ ] );
ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); xAccessGranted = prvTaskCanAccessRegion( xTaskMPURegion,
( uint32_t ) pvBuffer,
for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) ulBufferLength,
{ ulAccessRequested );
regionStartAddress = } while( ( pdFALSE == xAccessGranted ) &&
xTaskMpuSettings->xRegion[ i ].ulRegionBaseAddress; ( ulRegionIndex < portTOTAL_NUM_REGIONS_IN_TCB ) );
regionLength =
1 << ( ( xTaskMpuSettings->xRegion[ i ].ulRegionSize >> 1 ) + 1U );
regionEndAddress = regionStartAddress + regionLength;
if( ( ulBufferStartAddress >= regionStartAddress ) &&
( ulBufferEndAddress <= regionEndAddress ) )
{
if( tskMPU_READ_PERMISSION == ulAccessRequested )
{
/* MPU CTRL Register Access Permission for unprivileged Read
* is bX1X */
if( portMPU_PRIV_RO_USER_RO_EXEC &
xTaskMpuSettings->xRegion[ i ].ulRegionAttribute )
{
xAccessGranted = pdTRUE;
break;
}
}
/* MPU CTRL Register Access Permission for unprivileged write is
* b011 */
else if( tskMPU_WRITE_PERMISSION & ulAccessRequested )
{
if( portMPU_PRIV_RW_USER_RW_EXEC ==
( portMPU_PRIV_RW_USER_RW_EXEC &
xTaskMpuSettings->xRegion[ i ].ulRegionAttribute ) )
{
xAccessGranted = pdTRUE;
break;
}
}
}
}
}
} }
} }
return xAccessGranted; return xAccessGranted;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** @brief Determine if the FreeRTOS Task was created as a privileged task /** @brief Determine if the FreeRTOS Task was created as a privileged task