1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-24 07:18:09 +00:00

chore(core): use cortex-m33 stack protection

This commit is contained in:
cepetr 2023-11-14 11:53:24 +01:00 committed by TychoVrahe
parent 7e427432ea
commit 271bed8bf6
23 changed files with 121 additions and 48 deletions

View File

@ -129,6 +129,7 @@ SOURCE_BOOTLOADER = [
SOURCE_TREZORHAL = [ SOURCE_TREZORHAL = [
'embed/trezorhal/unix/boot_args.c', 'embed/trezorhal/unix/boot_args.c',
'embed/trezorhal/unix/display-unix.c', 'embed/trezorhal/unix/display-unix.c',
'embed/trezorhal/unix/fault_handlers.c',
'embed/trezorhal/unix/flash.c', 'embed/trezorhal/unix/flash.c',
'embed/trezorhal/unix/common.c', 'embed/trezorhal/unix/common.c',
'embed/trezorhal/unix/touch/touch.c', 'embed/trezorhal/unix/touch/touch.c',

View File

@ -24,6 +24,7 @@
#include "common.h" #include "common.h"
#include "compiler_traits.h" #include "compiler_traits.h"
#include "display.h" #include "display.h"
#include "fault_handlers.h"
#include "flash.h" #include "flash.h"
#include "image.h" #include "image.h"
#include "model.h" #include "model.h"
@ -257,6 +258,8 @@ int main(void) {
mpu_config_boardloader(); mpu_config_boardloader();
fault_handlers_init();
#ifdef USE_SDRAM #ifdef USE_SDRAM
sdram_init(); sdram_init();
#endif #endif

View File

@ -14,7 +14,7 @@ MEMORY {
} }
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100; _sstack = ORIGIN(SRAM2);
_estack = main_stack_base; _estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */ /* used by the startup code to populate variables used by the C code */
@ -80,7 +80,7 @@ SECTIONS {
} >SRAM1 } >SRAM1
.stack : ALIGN(8) { .stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */ . = 16K; /* Overflow causes UsageFault */
} >SRAM2 } >SRAM2
.sensitive : ALIGN(8) { .sensitive : ALIGN(8) {

View File

@ -5,6 +5,11 @@
.global reset_handler .global reset_handler
.type reset_handler, STT_FUNC .type reset_handler, STT_FUNC
reset_handler: reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #16 // padding
msr MSPLIM, r0
bl SystemInit bl SystemInit
// read the first rng data and save it // read the first rng data and save it

View File

@ -24,6 +24,7 @@
#include "common.h" #include "common.h"
#include "display.h" #include "display.h"
#include "display_utils.h" #include "display_utils.h"
#include "fault_handlers.h"
#include "flash.h" #include "flash.h"
#include "image.h" #include "image.h"
#include "lowlevel.h" #include "lowlevel.h"
@ -424,6 +425,8 @@ int bootloader_main(void) {
mpu_config_bootloader(); mpu_config_bootloader();
fault_handlers_init();
#ifdef TREZOR_EMULATOR #ifdef TREZOR_EMULATOR
// wait a bit so that the empty lock icon is visible // wait a bit so that the empty lock icon is visible
// (on a real device, we are waiting for touch init which takes longer) // (on a real device, we are waiting for touch init which takes longer)

View File

@ -14,7 +14,7 @@ MEMORY {
} }
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100; _sstack = ORIGIN(SRAM2);
_estack = main_stack_base; _estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */ /* used by the startup code to populate variables used by the C code */
@ -81,7 +81,7 @@ SECTIONS {
} >SRAM1 } >SRAM1
.stack : ALIGN(8) { .stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */ . = 16K; /* Overflow causes UsageFault */
} >SRAM2 } >SRAM2
.sensitive : ALIGN(512) { .sensitive : ALIGN(512) {

View File

@ -5,6 +5,11 @@
.global reset_handler .global reset_handler
.type reset_handler, STT_FUNC .type reset_handler, STT_FUNC
reset_handler: reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #16 // padding
msr MSPLIM, r0
// setup environment for subsequent stage of code // setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written ldr r2, =0 // r2 - the word-sized value to be written

View File

@ -14,7 +14,7 @@ MEMORY {
} }
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100; _sstack = ORIGIN(SRAM2);
_estack = main_stack_base; _estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */ /* used by the startup code to populate variables used by the C code */
@ -81,7 +81,7 @@ SECTIONS {
} >SRAM1 } >SRAM1
.stack : ALIGN(8) { .stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */ . = 16K; /* Overflow causes UsageFault */
} >SRAM2 } >SRAM2
.sensitive : ALIGN(512) { .sensitive : ALIGN(512) {

View File

@ -5,6 +5,11 @@
.global reset_handler .global reset_handler
.type reset_handler, STT_FUNC .type reset_handler, STT_FUNC
reset_handler: reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #16 // padding
msr MSPLIM, r0
// setup environment for subsequent stage of code // setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written ldr r2, =0 // r2 - the word-sized value to be written

View File

@ -41,6 +41,7 @@
#include "common.h" #include "common.h"
#include "compiler_traits.h" #include "compiler_traits.h"
#include "display.h" #include "display.h"
#include "fault_handlers.h"
#include "flash.h" #include "flash.h"
#include "image.h" #include "image.h"
#include "memzero.h" #include "memzero.h"
@ -146,10 +147,7 @@ int main(void) {
// Init peripherals // Init peripherals
pendsv_init(); pendsv_init();
#if !PRODUCTION fault_handlers_init();
// enable BUS fault and USAGE fault handlers
SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk);
#endif
#if defined TREZOR_MODEL_T #if defined TREZOR_MODEL_T
set_core_clock(CLOCK_180_MHZ); set_core_clock(CLOCK_180_MHZ);

View File

@ -14,7 +14,7 @@ MEMORY {
} }
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100; _sstack = ORIGIN(SRAM2);
_estack = main_stack_base; _estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */ /* used by the startup code to populate variables used by the C code */
@ -97,7 +97,7 @@ SECTIONS {
} >SRAM1 } >SRAM1
.stack : ALIGN(8) { .stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */ . = 16K; /* Overflow causes UsageFault */
} >SRAM2 } >SRAM2
.sensitive : ALIGN(512) { .sensitive : ALIGN(512) {

View File

@ -5,6 +5,11 @@
.global reset_handler .global reset_handler
.type reset_handler, STT_FUNC .type reset_handler, STT_FUNC
reset_handler: reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #16 // padding
msr MSPLIM, r0
// setup environment for subsequent stage of code // setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written ldr r2, =0 // r2 - the word-sized value to be written

View File

@ -27,6 +27,7 @@
#include "common.h" #include "common.h"
#include "display.h" #include "display.h"
#include "display_utils.h" #include "display_utils.h"
#include "fault_handlers.h"
#include "flash.h" #include "flash.h"
#include "i2c.h" #include "i2c.h"
#include "model.h" #include "model.h"
@ -570,6 +571,8 @@ int main(void) {
#endif #endif
mpu_config_prodtest(); mpu_config_prodtest();
fault_handlers_init();
drop_privileges(); drop_privileges();
display_clear(); display_clear();

View File

@ -14,7 +14,7 @@ MEMORY {
} }
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100; _sstack = ORIGIN(SRAM2);
_estack = main_stack_base; _estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */ /* used by the startup code to populate variables used by the C code */
@ -96,7 +96,7 @@ SECTIONS {
} >SRAM1 } >SRAM1
.stack : ALIGN(8) { .stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */ . = 16K; /* Overflow causes UsageFault */
} >SRAM2 } >SRAM2
.sensitive : ALIGN(512) { .sensitive : ALIGN(512) {

View File

@ -5,6 +5,11 @@
.global reset_handler .global reset_handler
.type reset_handler, STT_FUNC .type reset_handler, STT_FUNC
reset_handler: reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #16 // padding
msr MSPLIM, r0
// setup environment for subsequent stage of code // setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written ldr r2, =0 // r2 - the word-sized value to be written

View File

@ -14,7 +14,7 @@ MEMORY {
} }
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */ main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
_sstack = ORIGIN(SRAM2) + 0x100; _sstack = ORIGIN(SRAM2);
_estack = main_stack_base; _estack = main_stack_base;
/* used by the startup code to populate variables used by the C code */ /* used by the startup code to populate variables used by the C code */
@ -97,7 +97,7 @@ SECTIONS {
} >SRAM1 } >SRAM1
.stack : ALIGN(8) { .stack : ALIGN(8) {
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */ . = 16K + 0x100; /* Overflow causes UsageFault */
} >SRAM2 } >SRAM2
.sensitive : ALIGN(512) { .sensitive : ALIGN(512) {

View File

@ -5,6 +5,11 @@
.global reset_handler .global reset_handler
.type reset_handler, STT_FUNC .type reset_handler, STT_FUNC
reset_handler: reset_handler:
// set the stack protection
ldr r0, =_sstack
add r0, r0, #16 // padding
msr MSPLIM, r0
// setup environment for subsequent stage of code // setup environment for subsequent stage of code
ldr r2, =0 // r2 - the word-sized value to be written ldr r2, =0 // r2 - the word-sized value to be written

View File

@ -0,0 +1,7 @@
#ifndef TREZORHAL_FAULT_HANDLERS_H
#define TREZORHAL_FAULT_HANDLERS_H
// Initializes and enables fault handlers
void fault_handlers_init(void);
#endif // TREZORHAL_FAULT_HANDLERS_H

View File

@ -1,5 +1,10 @@
#include "common.h" #include "common.h"
void fault_handlers_init(void) {
// Enable BUS fault and USAGE fault handlers
SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk);
}
void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); } void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }
void MemManage_Handler_MM(void) { error_shutdown("INTERNAL ERROR", "(MM)"); } void MemManage_Handler_MM(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }

View File

@ -1,14 +1,28 @@
#include "common.h" #include "common.h"
void fault_handlers_init(void) {
// Enable BUS fault and USAGE fault handlers
SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk);
}
void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); } void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }
void MemManage_Handler_MM(void) { error_shutdown("INTERNAL ERROR", "(MM)"); } void MemManage_Handler(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
void MemManage_Handler_SO(void) { error_shutdown("INTERNAL ERROR", "(SO)"); }
void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); } void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); }
void UsageFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(UF)"); } void UsageFault_Handler(void) {
if (SCB->CFSR & SCB_CFSR_STKOF_Msk) {
// Stack overflow
extern uint8_t _estack; // linker script symbol
// Fix stack pointer
__set_MSP((uint32_t)&_estack);
error_shutdown("INTERNAL ERROR", "(SO)");
} else {
// Other error
error_shutdown("INTERNAL ERROR", "(UF)");
}
}
void SecureFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(SF)"); } void SecureFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(SF)"); }

View File

@ -130,16 +130,4 @@ shutdown_privileged:
ldr r0, =0 ldr r0, =0
b . // loop forever b . // loop forever
.global MemManage_Handler
.type MemManage_Handler, STT_FUNC
MemManage_Handler:
ldr r2, =_sstack
mrs r1, msp
ldr r0, =_estack
msr msp, r0
cmp r1, r2
IT lt
bllt MemManage_Handler_SO
bl MemManage_Handler_MM
.end .end

View File

@ -114,8 +114,7 @@ static void mpu_set_attributes() {
#define SIZE_128K (128 * 1024) #define SIZE_128K (128 * 1024)
#define SIZE_192K (192 * 1024) #define SIZE_192K (192 * 1024)
#define SIZE_320K (320 * 1024) #define SIZE_320K (320 * 1024)
#define SIZE_768K (768 * 1024) #define SIZE_2496K (2496 * 1024)
#define SIZE_1728K ((832 * 2 + 64) * 1024)
#define SIZE_3776K ((4096 - 320) * 1024) #define SIZE_3776K ((4096 - 320) * 1024)
#define SIZE_3904K ((4096 - 192) * 1024) #define SIZE_3904K ((4096 - 192) * 1024)
#define SIZE_4032K ((4096 - 64) * 1024) #define SIZE_4032K ((4096 - 64) * 1024)
@ -131,10 +130,10 @@ void mpu_config_boardloader() {
SET_REGION( 0, FLASH_BASE_S, SIZE_16K, FLASH_DATA, YES, NO ); // Secret SET_REGION( 0, FLASH_BASE_S, SIZE_16K, FLASH_DATA, YES, NO ); // Secret
SET_REGION( 1, FLASH_BASE_S + SIZE_16K, SIZE_48K, FLASH_CODE, NO, NO ); // Boardloader code SET_REGION( 1, FLASH_BASE_S + SIZE_16K, SIZE_48K, FLASH_CODE, NO, NO ); // Boardloader code
SET_REGION( 2, FLASH_BASE_S + SIZE_64K, SIZE_4032K, FLASH_DATA, YES, NO ); // Bootloader + Storage + Firmware SET_REGION( 2, FLASH_BASE_S + SIZE_64K, SIZE_4032K, FLASH_DATA, YES, NO ); // Bootloader + Storage + Firmware
SET_REGION( 3, SRAM1_BASE_S, SIZE_768K, SRAM, YES, NO ); // SRAM1 SET_REGION( 3, SRAM1_BASE_S, SIZE_2496K, SRAM, YES, NO ); // SRAM1/2/3/5
SET_REGION( 4, SRAM2_BASE_S + 0x100, SIZE_1728K - 0x100, SRAM, YES, NO ); // SRAM2/3/5 + stack guard SET_REGION( 4, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, NO ); // Frame buffer
SET_REGION( 5, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, NO ); // Frame buffer SET_REGION( 5, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, NO ); // Peripherals
SET_REGION( 6, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, NO ); // Peripherals DIS_REGION( 6 );
DIS_REGION( 7 ); DIS_REGION( 7 );
// clang-format on // clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
@ -148,11 +147,11 @@ void mpu_config_bootloader() {
SET_REGION( 0, FLASH_BASE_S, SIZE_64K, FLASH_DATA, YES, NO ); // Secret + Boardloader SET_REGION( 0, FLASH_BASE_S, SIZE_64K, FLASH_DATA, YES, NO ); // Secret + Boardloader
SET_REGION( 1, FLASH_BASE_S + SIZE_64K, SIZE_128K, FLASH_CODE, NO, NO ); // Bootloader code SET_REGION( 1, FLASH_BASE_S + SIZE_64K, SIZE_128K, FLASH_CODE, NO, NO ); // Bootloader code
SET_REGION( 2, FLASH_BASE_S + SIZE_192K, SIZE_3904K, FLASH_DATA, YES, NO ); // Storage + Firmware SET_REGION( 2, FLASH_BASE_S + SIZE_192K, SIZE_3904K, FLASH_DATA, YES, NO ); // Storage + Firmware
SET_REGION( 3, SRAM1_BASE_S, SIZE_768K, SRAM, YES, NO ); // SRAM1 SET_REGION( 3, SRAM1_BASE_S, SIZE_2496K, SRAM, YES, NO ); // SRAM1/2/3/5
SET_REGION( 4, SRAM2_BASE_S + 0x100, SIZE_1728K - 0x100, SRAM, YES, NO ); // SRAM2/3/5 + stack guard SET_REGION( 4, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, NO ); // Frame buffer
SET_REGION( 5, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, NO ); // Frame buffer SET_REGION( 5, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, NO ); // Peripherals
SET_REGION( 6, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, NO ); // Peripherals SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, NO ); // OTP
SET_REGION( 7, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, NO ); // OTP DIS_REGION( 7 );
// clang-format on // clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
} }
@ -164,11 +163,11 @@ void mpu_config_firmware() {
// REGION ADDRESS SIZE TYPE WRITE UNPRIV // REGION ADDRESS SIZE TYPE WRITE UNPRIV
SET_REGION( 0, FLASH_BASE_S + SIZE_192K, SIZE_128K, FLASH_DATA, YES, YES ); // Storage SET_REGION( 0, FLASH_BASE_S + SIZE_192K, SIZE_128K, FLASH_DATA, YES, YES ); // Storage
SET_REGION( 1, FLASH_BASE_S + SIZE_320K, SIZE_3776K, FLASH_CODE, NO, YES ); // Firmware SET_REGION( 1, FLASH_BASE_S + SIZE_320K, SIZE_3776K, FLASH_CODE, NO, YES ); // Firmware
SET_REGION( 2, SRAM1_BASE_S, SIZE_768K, SRAM, YES, YES ); // SRAM1 SET_REGION( 2, SRAM1_BASE_S, SIZE_2496K, SRAM, YES, YES ); // SRAM1/2/3/5
SET_REGION( 3, SRAM2_BASE_S + 0x100, SIZE_1728K - 0x100, SRAM, YES, YES ); // SRAM2/3/5 + stack guard SET_REGION( 3, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, YES ); // Frame buffer
SET_REGION( 4, GFXMMU_BUFFERS_S, SIZE_16M, SRAM, YES, YES ); // Frame buffer SET_REGION( 4, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, YES ); // Peripherals
SET_REGION( 5, PERIPH_BASE_S, SIZE_256M, PERIPHERAL, YES, YES ); // Peripherals SET_REGION( 5, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, YES ); // OTP
SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, YES ); // OTP DIS_REGION( 6 );
DIS_REGION( 7 ); DIS_REGION( 7 );
// clang-format on // clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);

View File

@ -0,0 +1,22 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <fault_handlers.h>
void fault_handlers_init(void) {}