Skip to content

Commit 78e0cc7

Browse files
ARMv8.1-M: Add task dedicated PAC key support (FreeRTOS#1195)
armv8.1-m: Add task dedicated PAC key To harden the security, each task is assigned a dedicated PAC key, so that attackers needs to guess the all the tasks' PAC keys right to exploit the system using Return Oriented Programming. The kernel is now updated to support the following: * A PAC key set with a random number generated and is saved in the task's context when a task is created. * As part of scheduling, the task's PAC key is stored/restored to/from the task's context when a task is unscheduled/scheduled from/to run. stack-overflow-check: Introduce portGET_CURRENT_TOP_OF_STACK macro When MPU wrapper v2 is used, the task's context is stored in TCB and `pxTopOfStack`` member of TCB points to the context location in TCB. We, therefore, need to read PSP to find the task's current top of stack. Signed-off-by: Ahmed Ismail <Ahmed.Ismail@arm.com>
1 parent c38427e commit 78e0cc7

File tree

87 files changed

+6725
-3593
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+6725
-3593
lines changed

.github/.cSpellWords.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ CLKSOURCE
106106
CLKSTA
107107
CLRB
108108
CLRF
109+
clrm
109110
CLRPSW
110111
CMCNT
111112
CMCON
@@ -678,6 +679,7 @@ pylint
678679
pytest
679680
pyyaml
680681
RAMPZ
682+
randomisation
681683
RASR
682684
Rationalised
683685
Raynald

include/portable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@
9393
#define portBASE_TYPE_EXIT_CRITICAL() taskEXIT_CRITICAL()
9494
#endif
9595

96+
#ifndef portGET_CURRENT_TOP_OF_STACK
97+
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { pxCurrentTopOfStack = ( StackType_t * ) pxCurrentTCB->pxTopOfStack; }
98+
#endif
99+
96100
#ifndef configSTACK_DEPTH_TYPE
97101
#define configSTACK_DEPTH_TYPE StackType_t
98102
#endif

include/stack_macros.h

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,13 @@
5757

5858
/* Only the current stack state is to be checked. */
5959
#define taskCHECK_FOR_STACK_OVERFLOW() \
60-
do { \
60+
do \
61+
{ \
62+
StackType_t * pxCurrentTopOfStack; \
63+
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
64+
\
6165
/* Is the currently saved stack pointer within the stack limit? */ \
62-
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \
66+
if( pxCurrentTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \
6367
{ \
6468
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
6569
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
@@ -72,36 +76,42 @@
7276
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
7377

7478
/* Only the current stack state is to be checked. */
75-
#define taskCHECK_FOR_STACK_OVERFLOW() \
76-
do { \
77-
\
78-
/* Is the currently saved stack pointer within the stack limit? */ \
79-
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
80-
{ \
81-
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
82-
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
83-
} \
79+
#define taskCHECK_FOR_STACK_OVERFLOW() \
80+
do \
81+
{ \
82+
StackType_t * pxCurrentTopOfStack; \
83+
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
84+
\
85+
/* Is the currently saved stack pointer within the stack limit? */ \
86+
if( pxCurrentTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
87+
{ \
88+
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
89+
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
90+
} \
8491
} while( 0 )
8592

8693
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
8794
/*-----------------------------------------------------------*/
8895

8996
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
9097

91-
#define taskCHECK_FOR_STACK_OVERFLOW() \
92-
do { \
93-
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
94-
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \
95-
\
96-
if( ( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) || \
97-
( pulStack[ 0 ] != ulCheckValue ) || \
98-
( pulStack[ 1 ] != ulCheckValue ) || \
99-
( pulStack[ 2 ] != ulCheckValue ) || \
100-
( pulStack[ 3 ] != ulCheckValue ) ) \
101-
{ \
102-
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
103-
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
104-
} \
98+
#define taskCHECK_FOR_STACK_OVERFLOW() \
99+
do \
100+
{ \
101+
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
102+
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \
103+
StackType_t * pxCurrentTopOfStack; \
104+
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
105+
\
106+
if( ( pxCurrentTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) || \
107+
( pulStack[ 0 ] != ulCheckValue ) || \
108+
( pulStack[ 1 ] != ulCheckValue ) || \
109+
( pulStack[ 2 ] != ulCheckValue ) || \
110+
( pulStack[ 3 ] != ulCheckValue ) ) \
111+
{ \
112+
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
113+
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
114+
} \
105115
} while( 0 )
106116

107117
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
@@ -110,18 +120,20 @@
110120
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
111121

112122
#define taskCHECK_FOR_STACK_OVERFLOW() \
113-
do { \
123+
do \
124+
{ \
114125
int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
115126
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
116127
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
117128
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
118129
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
119130
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
120-
\
131+
StackType_t * pxCurrentTopOfStack; \
132+
portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
121133
\
122134
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
123135
\
124-
if( ( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) || \
136+
if( ( pxCurrentTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) || \
125137
( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) ) \
126138
{ \
127139
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \

0 commit comments

Comments
 (0)