Skip to content

Commit 029545f

Browse files
committed
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 pushed onto the task's stack when a task is created. * As part of scheduling, the task's PAC key is stacked/unstacked to/from the task's stack when a task is unscheduled/scheduled from/to run. Signed-off-by: Ahmed Ismail <Ahmed.Ismail@arm.com>
1 parent c84fc72 commit 029545f

File tree

63 files changed

+4247
-1292
lines changed

Some content is hidden

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

63 files changed

+4247
-1292
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

portable/ARMv8M/non_secure/port.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,6 +1582,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
15821582
}
15831583
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
15841584

1585+
#if ( configENABLE_PAC == 1 )
1586+
{
1587+
uint32_t ulTaskPacKey[ 4 ], i;
1588+
1589+
vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) );
1590+
1591+
for( i = 0; i < 4; i++ )
1592+
{
1593+
xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ];
1594+
ulIndex++;
1595+
}
1596+
}
1597+
#endif /* configENABLE_PAC */
1598+
15851599
return &( xMPUSettings->ulContext[ ulIndex ] );
15861600
}
15871601

@@ -1664,6 +1678,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
16641678
}
16651679
#endif /* portPRELOAD_REGISTERS */
16661680

1681+
#if ( configENABLE_PAC == 1 )
1682+
{
1683+
uint32_t ulTaskPacKey[ 4 ], i;
1684+
1685+
vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) );
1686+
1687+
for( i = 0; i < 4; i++ )
1688+
{
1689+
pxTopOfStack--;
1690+
*pxTopOfStack = ulTaskPacKey[ i ];
1691+
}
1692+
}
1693+
#endif /* configENABLE_PAC */
1694+
16671695
return pxTopOfStack;
16681696
}
16691697

portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c

Lines changed: 119 additions & 71 deletions
Large diffs are not rendered by default.

portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@
100100
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
101101
" \n"
102102
" restore_special_regs_first_task: \n"
103+
#if ( configENABLE_PAC == 1 )
104+
" ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */
105+
" msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
106+
" msr PAC_KEY_P_1, r3 \n"
107+
" msr PAC_KEY_P_2, r4 \n"
108+
" msr PAC_KEY_P_3, r5 \n"
109+
" clrm {r2-r5} \n" /* Clear r2-r5. */
110+
#endif /* configENABLE_PAC */
103111
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
104112
" msr psp, r2 \n"
105113
" msr psplim, r3 \n"
@@ -130,6 +138,15 @@
130138
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
131139
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
132140
" \n"
141+
#if ( configENABLE_PAC == 1 )
142+
" ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */
143+
" msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
144+
" msr PAC_KEY_P_2, r2 \n"
145+
" msr PAC_KEY_P_1, r3 \n"
146+
" msr PAC_KEY_P_0, r4 \n"
147+
" clrm {r1-r4} \n" /* Clear r1-r4. */
148+
#endif /* configENABLE_PAC */
149+
" \n"
133150
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
134151
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
135152
" mrs r1, control \n" /* Obtain current control register value. */
@@ -270,7 +287,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
270287
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */
271288
" sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
272289
#endif /* configENABLE_FPU || configENABLE_MVE */
273-
" \n"
274290
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */
275291
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
276292
" stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */
@@ -279,6 +295,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
279295
" mrs r3, psplim \n" /* r3 = PSPLIM. */
280296
" mrs r4, control \n" /* r4 = CONTROL. */
281297
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
298+
#if ( configENABLE_PAC == 1 )
299+
" mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */
300+
" mrs r3, PAC_KEY_P_1 \n"
301+
" mrs r4, PAC_KEY_P_2 \n"
302+
" mrs r5, PAC_KEY_P_3 \n"
303+
" stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */
304+
" clrm {r2-r5} \n" /* Clear r2-r5. */
305+
#endif /* configENABLE_PAC */
282306
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
283307
" \n"
284308
" select_next_task: \n"
@@ -337,6 +361,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
337361
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
338362
" \n"
339363
" restore_special_regs: \n"
364+
#if ( configENABLE_PAC == 1 )
365+
" ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */
366+
" msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
367+
" msr PAC_KEY_P_1, r3 \n"
368+
" msr PAC_KEY_P_2, r4 \n"
369+
" msr PAC_KEY_P_3, r5 \n"
370+
" clrm {r2-r5} \n" /* Clear r2-r5. */
371+
#endif /* configENABLE_PAC */
340372
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
341373
" msr psp, r2 \n"
342374
" msr psplim, r3 \n"
@@ -381,6 +413,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
381413
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
382414
" stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
383415
" \n"
416+
#if ( configENABLE_PAC == 1 )
417+
" mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */
418+
" mrs r2, PAC_KEY_P_2 \n"
419+
" mrs r3, PAC_KEY_P_1 \n"
420+
" mrs r4, PAC_KEY_P_0 \n"
421+
" stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */
422+
" clrm {r1-r4} \n" /* Clear r1-r4. */
423+
#endif /* configENABLE_PAC */
424+
" \n"
384425
" ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
385426
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
386427
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
@@ -397,6 +438,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
397438
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
398439
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
399440
" \n"
441+
#if ( configENABLE_PAC == 1 )
442+
" ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */
443+
" msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
444+
" msr PAC_KEY_P_2, r3 \n"
445+
" msr PAC_KEY_P_1, r4 \n"
446+
" msr PAC_KEY_P_0, r5 \n"
447+
" clrm {r2-r5} \n" /* Clear r2-r5. */
448+
#endif /* configENABLE_PAC */
449+
" \n"
400450
" ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
401451
" \n"
402452
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )

0 commit comments

Comments
 (0)