Skip to content

Commit b4972f4

Browse files
committed
Mask MPU region base addresses when writing to MPU_RBAR on ARM_CM3/4
Bits 0-4 are reserved for VALID and REGION, while ADDR spans at most bits 5-31 (bits 5-7 are sometimes reserved and not assigned to ADDR field). 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, and doesn't ensure that reserved field from bits 5-7 are not written to, but protects the VALID and REGION fields.
1 parent 8be86d4 commit b4972f4

4 files changed

Lines changed: 32 additions & 28 deletions

File tree

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

portable/GCC/ARM_CM4_MPU/port.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ typedef void ( * portISR_t )( void );
105105
#define portMPU_REGION_ENABLE ( 0x01UL )
106106
#define portPERIPHERALS_START_ADDRESS 0x40000000UL
107107
#define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL
108+
#define portMPU_RBAR_ADDRESS_MASK 0xFFFFFFE0
108109

109110
/* Constants required to access and manipulate the SysTick and other FreeRTOS
110111
* interrupts. */
@@ -1282,7 +1283,7 @@ static void prvSetupMPU( void )
12821283
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
12831284
{
12841285
/* First setup the unprivileged flash for unprivileged read only access. */
1285-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */
1286+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __FLASH_segment_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
12861287
( portMPU_REGION_VALID ) |
12871288
( portUNPRIVILEGED_FLASH_REGION );
12881289

@@ -1293,7 +1294,7 @@ static void prvSetupMPU( void )
12931294

12941295
/* Setup the privileged flash for privileged only access. This is where
12951296
* the kernel code is placed. */
1296-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */
1297+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
12971298
( portMPU_REGION_VALID ) |
12981299
( portPRIVILEGED_FLASH_REGION );
12991300

@@ -1304,7 +1305,7 @@ static void prvSetupMPU( void )
13041305

13051306
/* Setup the privileged data RAM region. This is where the kernel data
13061307
* is placed. */
1307-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */
1308+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __privileged_data_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
13081309
( portMPU_REGION_VALID ) |
13091310
( portPRIVILEGED_RAM_REGION );
13101311

@@ -1316,7 +1317,7 @@ static void prvSetupMPU( void )
13161317

13171318
/* By default allow everything to access the general peripherals. The
13181319
* system peripherals and registers are protected. */
1319-
portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) |
1320+
portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS & portMPU_RBAR_ADDRESS_MASK ) |
13201321
( portMPU_REGION_VALID ) |
13211322
( portGENERAL_PERIPHERALS_REGION );
13221323

@@ -1426,7 +1427,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
14261427
{
14271428
/* No MPU regions are specified so allow access to all RAM. */
14281429
xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
1429-
( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */
1430+
( ( ( uint32_t ) __SRAM_segment_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
14301431
( portMPU_REGION_VALID ) |
14311432
( portSTACK_REGION ); /* Region number. */
14321433

@@ -1462,7 +1463,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
14621463
{
14631464
/* Define the region that allows access to the stack. */
14641465
xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
1465-
( ( uint32_t ) pxBottomOfStack ) |
1466+
( ( ( uint32_t ) pxBottomOfStack & portMPU_RBAR_ADDRESS_MASK ) ) |
14661467
( portMPU_REGION_VALID ) |
14671468
( portSTACK_REGION ); /* Region number. */
14681469

@@ -1490,7 +1491,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
14901491
* xRegions into the CM4 specific MPU settings that are then
14911492
* stored in xMPUSettings. */
14921493
xMPUSettings->xRegion[ ul ].ulRegionBaseAddress =
1493-
( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) |
1494+
( ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK ) |
14941495
( portMPU_REGION_VALID ) |
14951496
( ul - 1UL ); /* Region number. */
14961497

portable/IAR/ARM_CM4F_MPU/port.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ typedef void ( * portISR_t )( void );
106106
#define portMPU_REGION_ENABLE ( 0x01UL )
107107
#define portPERIPHERALS_START_ADDRESS 0x40000000UL
108108
#define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL
109+
#define portMPU_RBAR_ADDRESS_MASK 0xFFFFFFE0
109110

110111
/* ...then bits in the registers. */
111112
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
@@ -1071,7 +1072,7 @@ static void prvSetupMPU( void )
10711072
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
10721073
{
10731074
/* First setup the unprivileged flash for unprivileged read only access. */
1074-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */
1075+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __FLASH_segment_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
10751076
( portMPU_REGION_VALID ) |
10761077
( portUNPRIVILEGED_FLASH_REGION );
10771078

@@ -1082,7 +1083,7 @@ static void prvSetupMPU( void )
10821083

10831084
/* Setup the privileged flash for privileged only access. This is where
10841085
* the kernel code is placed. */
1085-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */
1086+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
10861087
( portMPU_REGION_VALID ) |
10871088
( portPRIVILEGED_FLASH_REGION );
10881089

@@ -1093,7 +1094,7 @@ static void prvSetupMPU( void )
10931094

10941095
/* Setup the privileged data RAM region. This is where the kernel data
10951096
* is placed. */
1096-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */
1097+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __privileged_data_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
10971098
( portMPU_REGION_VALID ) |
10981099
( portPRIVILEGED_RAM_REGION );
10991100

@@ -1105,7 +1106,7 @@ static void prvSetupMPU( void )
11051106

11061107
/* By default allow everything to access the general peripherals. The
11071108
* system peripherals and registers are protected. */
1108-
portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) |
1109+
portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS & portMPU_RBAR_ADDRESS_MASK ) |
11091110
( portMPU_REGION_VALID ) |
11101111
( portGENERAL_PERIPHERALS_REGION );
11111112

@@ -1162,7 +1163,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
11621163
{
11631164
/* No MPU regions are specified so allow access to all RAM. */
11641165
xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
1165-
( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */
1166+
( ( ( uint32_t ) __SRAM_segment_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
11661167
( portMPU_REGION_VALID ) |
11671168
( portSTACK_REGION ); /* Region number. */
11681169

@@ -1198,7 +1199,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
11981199
{
11991200
/* Define the region that allows access to the stack. */
12001201
xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
1201-
( ( uint32_t ) pxBottomOfStack ) |
1202+
( ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK ) |
12021203
( portMPU_REGION_VALID ) |
12031204
( portSTACK_REGION ); /* Region number. */
12041205

@@ -1226,7 +1227,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
12261227
* xRegions into the CM4 specific MPU settings that are then
12271228
* stored in xMPUSettings. */
12281229
xMPUSettings->xRegion[ ul ].ulRegionBaseAddress =
1229-
( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) |
1230+
( ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK ) |
12301231
( portMPU_REGION_VALID ) |
12311232
( ul - 1UL ); /* Region number. */
12321233

portable/RVDS/ARM_CM4_MPU/port.c

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

9899
/* Constants required to access and manipulate the SysTick and other FreeRTOS
99100
* interrupts. */
@@ -1282,7 +1283,7 @@ static void prvSetupMPU( void )
12821283
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
12831284
{
12841285
/* First setup the unprivileged flash for unprivileged read only access. */
1285-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */
1286+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __FLASH_segment_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
12861287
( portMPU_REGION_VALID ) |
12871288
( portUNPRIVILEGED_FLASH_REGION );
12881289

@@ -1293,7 +1294,7 @@ static void prvSetupMPU( void )
12931294

12941295
/* Setup the privileged flash for privileged only access. This is where
12951296
* the kernel code is placed. */
1296-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */
1297+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
12971298
( portMPU_REGION_VALID ) |
12981299
( portPRIVILEGED_FLASH_REGION );
12991300

@@ -1304,7 +1305,7 @@ static void prvSetupMPU( void )
13041305

13051306
/* Setup the privileged data RAM region. This is where the kernel data
13061307
* is placed. */
1307-
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */
1308+
portMPU_REGION_BASE_ADDRESS_REG = ( ( ( uint32_t ) __privileged_data_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
13081309
( portMPU_REGION_VALID ) |
13091310
( portPRIVILEGED_RAM_REGION );
13101311

@@ -1316,7 +1317,7 @@ static void prvSetupMPU( void )
13161317

13171318
/* By default allow everything to access the general peripherals. The
13181319
* system peripherals and registers are protected. */
1319-
portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) |
1320+
portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS & portMPU_RBAR_ADDRESS_MASK ) |
13201321
( portMPU_REGION_VALID ) |
13211322
( portGENERAL_PERIPHERALS_REGION );
13221323

@@ -1416,7 +1417,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
14161417
{
14171418
/* No MPU regions are specified so allow access to all RAM. */
14181419
xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
1419-
( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */
1420+
( ( ( uint32_t ) __SRAM_segment_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | /* Base address. */
14201421
( portMPU_REGION_VALID ) |
14211422
( portSTACK_REGION ); /* Region number. */
14221423

@@ -1452,7 +1453,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
14521453
{
14531454
/* Define the region that allows access to the stack. */
14541455
xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =
1455-
( ( uint32_t ) pxBottomOfStack ) |
1456+
( ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK ) |
14561457
( portMPU_REGION_VALID ) |
14571458
( portSTACK_REGION ); /* Region number. */
14581459

@@ -1480,7 +1481,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
14801481
* xRegions into the CM4 specific MPU settings that are then
14811482
* stored in xMPUSettings. */
14821483
xMPUSettings->xRegion[ ul ].ulRegionBaseAddress =
1483-
( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) |
1484+
( ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK ) |
14841485
( portMPU_REGION_VALID ) |
14851486
( ul - 1UL ); /* Region number. */
14861487

0 commit comments

Comments
 (0)