mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-11-05 11:12:27 -05:00
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>
This commit is contained in:
parent
c84fc7226e
commit
029545f4ad
63 changed files with 4247 additions and 1292 deletions
|
|
@ -1582,6 +1582,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
}
|
||||
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||
|
||||
#if ( configENABLE_PAC == 1 )
|
||||
{
|
||||
uint32_t ulTaskPacKey[ 4 ], i;
|
||||
|
||||
vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) );
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ];
|
||||
ulIndex++;
|
||||
}
|
||||
}
|
||||
#endif /* configENABLE_PAC */
|
||||
|
||||
return &( xMPUSettings->ulContext[ ulIndex ] );
|
||||
}
|
||||
|
||||
|
|
@ -1664,6 +1678,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
|||
}
|
||||
#endif /* portPRELOAD_REGISTERS */
|
||||
|
||||
#if ( configENABLE_PAC == 1 )
|
||||
{
|
||||
uint32_t ulTaskPacKey[ 4 ], i;
|
||||
|
||||
vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) );
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ulTaskPacKey[ i ];
|
||||
}
|
||||
}
|
||||
#endif /* configENABLE_PAC */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,14 @@
|
|||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs_first_task: \n"
|
||||
#if ( configENABLE_PAC == 1 )
|
||||
" ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */
|
||||
" msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||
" msr PAC_KEY_P_1, r3 \n"
|
||||
" msr PAC_KEY_P_2, r4 \n"
|
||||
" msr PAC_KEY_P_3, r5 \n"
|
||||
" clrm {r2-r5} \n" /* Clear r2-r5. */
|
||||
#endif /* configENABLE_PAC */
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
|
|
@ -130,6 +138,15 @@
|
|||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||
" \n"
|
||||
#if ( configENABLE_PAC == 1 )
|
||||
" ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */
|
||||
" msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||
" msr PAC_KEY_P_2, r2 \n"
|
||||
" msr PAC_KEY_P_1, r3 \n"
|
||||
" msr PAC_KEY_P_0, r4 \n"
|
||||
" clrm {r1-r4} \n" /* Clear r1-r4. */
|
||||
#endif /* configENABLE_PAC */
|
||||
" \n"
|
||||
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
||||
" mrs r1, control \n" /* Obtain current control register value. */
|
||||
|
|
@ -270,7 +287,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||
" sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
|
||||
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||
" \n"
|
||||
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */
|
||||
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||
" stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||
|
|
@ -279,6 +295,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||
#if ( configENABLE_PAC == 1 )
|
||||
" mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */
|
||||
" mrs r3, PAC_KEY_P_1 \n"
|
||||
" mrs r4, PAC_KEY_P_2 \n"
|
||||
" mrs r5, PAC_KEY_P_3 \n"
|
||||
" stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */
|
||||
" clrm {r2-r5} \n" /* Clear r2-r5. */
|
||||
#endif /* configENABLE_PAC */
|
||||
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||
" \n"
|
||||
" select_next_task: \n"
|
||||
|
|
@ -337,6 +361,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||
" \n"
|
||||
" restore_special_regs: \n"
|
||||
#if ( configENABLE_PAC == 1 )
|
||||
" ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */
|
||||
" msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||
" msr PAC_KEY_P_1, r3 \n"
|
||||
" msr PAC_KEY_P_2, r4 \n"
|
||||
" msr PAC_KEY_P_3, r5 \n"
|
||||
" clrm {r2-r5} \n" /* Clear r2-r5. */
|
||||
#endif /* configENABLE_PAC */
|
||||
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||
" msr psp, r2 \n"
|
||||
" msr psplim, r3 \n"
|
||||
|
|
@ -381,6 +413,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
||||
" \n"
|
||||
#if ( configENABLE_PAC == 1 )
|
||||
" mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */
|
||||
" mrs r2, PAC_KEY_P_2 \n"
|
||||
" mrs r3, PAC_KEY_P_1 \n"
|
||||
" mrs r4, PAC_KEY_P_0 \n"
|
||||
" stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */
|
||||
" clrm {r1-r4} \n" /* Clear r1-r4. */
|
||||
#endif /* configENABLE_PAC */
|
||||
" \n"
|
||||
" ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
|
|
@ -397,6 +438,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
|||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||
" \n"
|
||||
#if ( configENABLE_PAC == 1 )
|
||||
" ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */
|
||||
" msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||
" msr PAC_KEY_P_2, r3 \n"
|
||||
" msr PAC_KEY_P_1, r4 \n"
|
||||
" msr PAC_KEY_P_0, r5 \n"
|
||||
" clrm {r2-r5} \n" /* Clear r2-r5. */
|
||||
#endif /* configENABLE_PAC */
|
||||
" \n"
|
||||
" ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||
" \n"
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/*
|
||||
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* Copyright 2024 Arm Limited and/or its affiliates
|
||||
* <open-source-office@arm.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
|
|
@ -125,6 +127,18 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_PAC == 1 )
|
||||
|
||||
/**
|
||||
* @brief Generates 128-bit task's random PAC key.
|
||||
*
|
||||
* @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be
|
||||
* filled with a 128-bit random number.
|
||||
*/
|
||||
void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey );
|
||||
|
||||
#endif /* configENABLE_PAC */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
|
|
@ -223,63 +237,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
|||
*/
|
||||
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
|
||||
* 16 16 8 8 5 16 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 70
|
||||
|
||||
#elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) )
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||
* 16 16 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 54
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
#elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
* +-----------+---------------+----------+-----------------+----------------------+------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><-----------><---->
|
||||
* 16 16 8 8 4 16 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 69
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | | | PC, xPSR | EXC_RETURN | |
|
||||
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||
* 16 16 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 53
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||
|
||||
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
* +----------+-----------------+------------------------------+------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | | |
|
||||
* +----------+-----------------+------------------------------+------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><-----------><---->
|
||||
* 8 8 5 16 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 38
|
||||
|
||||
#elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||
* +----------+-----------------+------------------------------+-----+
|
||||
*
|
||||
* <---------><----------------><------------------------------><---->
|
||||
* 8 8 5 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 22
|
||||
|
||||
#elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
|
||||
|
||||
/*
|
||||
* +----------+-----------------+----------------------+------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
|
||||
* | | PC, xPSR | EXC_RETURN | | |
|
||||
* +----------+-----------------+----------------------+------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><-----------><---->
|
||||
* 8 8 4 16 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 37
|
||||
|
||||
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
|
||||
/*
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||
* | | PC, xPSR | EXC_RETURN | |
|
||||
* +----------+-----------------+----------------------+-----+
|
||||
*
|
||||
* <---------><----------------><----------------------><---->
|
||||
* 8 8 4 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 21
|
||||
|
||||
#endif /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||
|
||||
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue