Skip to content

Commit b13b884

Browse files
committed
Mask MPU region base addresses when writing to MPU_RBAR
Bits 0-4 are reserved for VALID and REGION, while ADDR spans only bits 5-31. Masking ensures that a misaligned base address cannot modify less significant bits in the attribute reserved for other use. Failing to mask the address may allow a malicious user to pass in misaligned addresses in a user-defined region or as stack buffer which could in turn override the settings for higher-priority kernel-defined regions. This change doesn't guarantee that only properly aligned addresses are written to the ADDR field of the register, but protects the VALID and REGION fields.
1 parent 8be86d4 commit b13b884

1 file changed

Lines changed: 8 additions & 7 deletions

File tree

  • portable/GCC/ARM_CM3_MPU

portable/GCC/ARM_CM3_MPU/port.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ typedef void ( * portISR_t )( void );
9595
#define portMPU_REGION_ENABLE ( 0x01UL )
9696
#define portPERIPHERALS_START_ADDRESS 0x40000000UL
9797
#define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL
98+
#define portMPU_RBAR_ADDRESS_MASK 0xFFFFFFE0
9899

99100
/* Constants required to access and manipulate the SysTick and other FreeRTOS
100101
* interrupts. */
@@ -1137,7 +1138,7 @@ static void prvSetupMPU( void )
11371138
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
11381139
{
11391140
/* First setup the unprivileged flash for unprivileged read only access. */
1140-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */
1141+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __FLASH_segment_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
11411142
( portMPU_REGION_VALID ) |
11421143
( portUNPRIVILEGED_FLASH_REGION );
11431144

@@ -1148,7 +1149,7 @@ static void prvSetupMPU( void )
11481149

11491150
/* Setup the privileged flash for privileged only access. This is where
11501151
* the kernel code is * placed. */
1151-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */
1152+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
11521153
( portMPU_REGION_VALID ) |
11531154
( portPRIVILEGED_FLASH_REGION );
11541155

@@ -1159,7 +1160,7 @@ static void prvSetupMPU( void )
11591160

11601161
/* Setup the privileged data RAM region. This is where the kernel data
11611162
* is placed. */
1162-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */
1163+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __privileged_data_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
11631164
( portMPU_REGION_VALID ) |
11641165
( portPRIVILEGED_RAM_REGION );
11651166

@@ -1171,7 +1172,7 @@ static void prvSetupMPU( void )
11711172

11721173
/* By default allow everything to access the general peripherals. The
11731174
* system peripherals and registers are protected. */
1174-
portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) |
1175+
portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS & portMPU_RBAR_ADDRESS_MASK ) |
11751176
( portMPU_REGION_VALID ) |
11761177
( portGENERAL_PERIPHERALS_REGION );
11771178

@@ -1281,7 +1282,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
12811282
{
12821283
/* No MPU regions are specified so allow access to all RAM. */
12831284
xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
1284-
( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */
1285+
( ( ( uint32_t ) __SRAM_segment_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
12851286
( portMPU_REGION_VALID ) |
12861287
( portSTACK_REGION ); /* Region number. */
12871288

@@ -1317,7 +1318,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
13171318
{
13181319
/* Define the region that allows access to the stack. */
13191320
xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
1320-
( ( uint32_t ) pxBottomOfStack ) |
1321+
( ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK ) |
13211322
( portMPU_REGION_VALID ) |
13221323
( portSTACK_REGION ); /* Region number. */
13231324

@@ -1344,7 +1345,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
13441345
* xRegions into the CM3 specific MPU settings that are then
13451346
* stored in xMPUSettings. */
13461347
xMPUSettings->xRegion[ ul ].ulRegionBaseAddress =
1347-
( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) |
1348+
( ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK ) |
13481349
( portMPU_REGION_VALID ) |
13491350
( ul - 1UL ); /* Region number. */
13501351

0 commit comments

Comments
 (0)