Skip to content

Commit

Permalink
refactor(core): adjust system api for syscall verifier
Browse files Browse the repository at this point in the history
[no changelog]
  • Loading branch information
cepetr committed Sep 30, 2024
1 parent aa1ccb8 commit 7f7193a
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 116 deletions.
36 changes: 19 additions & 17 deletions core/embed/rust/src/trezorhal/fatal_error.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
mod ffi {
extern "C" {
// error_handling.h
pub fn error_shutdown(msg: *const cty::c_char) -> !;
// system.h
pub fn system_exit_error_ex(
title: *const cty::c_char,
title_len: usize,
message: *const cty::c_char,
message_len: usize,
footer: *const cty::c_char,
footer_len: usize,
) -> !;
}
}

pub fn error_shutdown(msg: &str) -> ! {
const MAX_LEN: usize = 63;
let mut buffer: [u8; MAX_LEN + 1] = [0; MAX_LEN + 1];

// Copy the message to the buffer
let msg_bytes = msg.as_bytes();
let len = if msg_bytes.len() < MAX_LEN {
msg_bytes.len()
} else {
MAX_LEN
};
buffer[..len].copy_from_slice(&msg_bytes[..len]);

unsafe {
// SAFETY: `buffer` is a valid null-terminated string
// and the function never returns.
ffi::error_shutdown(buffer.as_ptr() as *const cty::c_char);
// SAFETY: we pass a valid string to the C function
// and the function does not return.
ffi::system_exit_error_ex(
core::ptr::null(),
0,
msg.as_ptr() as *const cty::c_char,
msg.len(),
core::ptr::null(),
0,
);
}
}

Expand Down
18 changes: 12 additions & 6 deletions core/embed/trezorhal/stm32f4/syscall_dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,23 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
case SYSCALL_SYSTEM_EXIT_ERROR: {
systask_t *task = systask_active();
const char *title = (const char *)args[0];
const char *message = (const char *)args[1];
const char *footer = (const char *)args[2];
systask_exit_error(task, title, message, footer);
size_t title_len = (size_t)args[1];
const char *message = (const char *)args[2];
size_t message_len = (size_t)args[3];
const char *footer = (const char *)args[4];
size_t footer_len = (size_t)args[5];
systask_exit_error(task, title, title_len, message, message_len, footer,
footer_len);
} break;

case SYSCALL_SYSTEM_EXIT_FATAL: {
systask_t *task = systask_active();
const char *message = (const char *)args[0];
const char *file = (const char *)args[1];
int line = (int)args[2];
systask_exit_fatal(task, message, file, line);
size_t message_len = (size_t)args[1];
const char *file = (const char *)args[2];
size_t file_len = (size_t)args[3];
int line = (int)args[4];
systask_exit_fatal(task, message, message_len, file, file_len, line);
} break;

case SYSCALL_SYSTICK_CYCLES: {
Expand Down
16 changes: 9 additions & 7 deletions core/embed/trezorhal/stm32f4/syscall_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,19 @@ void system_exit(int exit_code) {
;
}

void system_exit_error(const char *title, const char *message,
const char *footer) {
syscall_invoke3((uint32_t)title, (uint32_t)message, (uint32_t)footer,
SYSCALL_SYSTEM_EXIT_ERROR);
void system_exit_error_ex(const char *title, size_t title_len,
const char *message, size_t message_len,
const char *footer, size_t footer_len) {
syscall_invoke6((uint32_t)title, title_len, (uint32_t)message, message_len,
(uint32_t)footer, footer_len, SYSCALL_SYSTEM_EXIT_ERROR);
while (1)
;
}

void system_exit_fatal(const char *message, const char *file, int line) {
syscall_invoke3((uint32_t)message, (uint32_t)file, line,
SYSCALL_SYSTEM_EXIT_FATAL);
void system_exit_fatal_ex(const char *message, size_t message_len,
const char *file, size_t file_len, int line) {
syscall_invoke5((uint32_t)message, message_len, (uint32_t)file, file_len,
line, SYSCALL_SYSTEM_EXIT_FATAL);
while (1)
;
}
Expand Down
24 changes: 16 additions & 8 deletions core/embed/trezorhal/stm32f4/systask.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <string.h>

#include "bootutils.h"
#include "common.h"
#include "irq.h"
#include "mpu.h"
#include "syscall.h"
Expand Down Expand Up @@ -234,8 +235,9 @@ void systask_exit(systask_t* task, int exit_code) {
systask_kill(task);
}

void systask_exit_error(systask_t* task, const char* title, const char* message,
const char* footer) {
void systask_exit_error(systask_t* task, const char* title, size_t title_len,
const char* message, size_t message_len,
const char* footer, size_t footer_len) {
systask_scheduler_t* scheduler = &g_systask_scheduler;

if (task == NULL) {
Expand All @@ -250,21 +252,25 @@ void systask_exit_error(systask_t* task, const char* title, const char* message,
pminfo->privileged = (task == &scheduler->kernel_task);

if (title != NULL) {
strncpy(pminfo->error.title, title, sizeof(pminfo->error.title) - 1);
size_t len = MIN(title_len, sizeof(pminfo->error.title) - 1);
strncpy(pminfo->error.title, title, len);
}

if (message != NULL) {
strncpy(pminfo->error.message, message, sizeof(pminfo->error.message) - 1);
size_t len = MIN(message_len, sizeof(pminfo->error.message) - 1);
strncpy(pminfo->error.message, message, len);
}

if (footer != NULL) {
strncpy(pminfo->error.footer, footer, sizeof(pminfo->error.footer) - 1);
size_t len = MIN(footer_len, sizeof(pminfo->error.footer) - 1);
strncpy(pminfo->error.footer, footer, len);
}

systask_kill(task);
}

void systask_exit_fatal(systask_t* task, const char* message, const char* file,
void systask_exit_fatal(systask_t* task, const char* message,
size_t message_len, const char* file, size_t file_len,
int line) {
systask_scheduler_t* scheduler = &g_systask_scheduler;

Expand All @@ -280,11 +286,13 @@ void systask_exit_fatal(systask_t* task, const char* message, const char* file,
pminfo->privileged = (task == &scheduler->kernel_task);

if (message != NULL) {
strncpy(pminfo->fatal.expr, message, sizeof(pminfo->fatal.expr) - 1);
size_t len = MIN(message_len, sizeof(pminfo->fatal.expr) - 1);
strncpy(pminfo->fatal.expr, message, len);
}

if (file != NULL) {
strncpy(pminfo->fatal.file, file, sizeof(pminfo->fatal.file) - 1);
size_t len = MIN(file_len, sizeof(pminfo->fatal.file) - 1);
strncpy(pminfo->fatal.file, file, len);
}

pminfo->fatal.line = line;
Expand Down
124 changes: 72 additions & 52 deletions core/embed/trezorhal/stm32f4/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,19 @@

#include STM32_HAL_H

#include "system.h"
#include <string.h>

#include "bootutils.h"
#include "mpu.h"
#include "systask.h"
#include "system.h"
#include "systick.h"
#include "systimer.h"

#ifndef HardFault_IRQn
#define HardFault_IRQn (-13) // not defined in stm32lib/cmsis/stm32429xx.h
#endif

#ifdef KERNEL_MODE

void system_init(systask_error_handler_t error_handler) {
Expand All @@ -38,61 +44,18 @@ void system_init(systask_error_handler_t error_handler) {

void system_exit(int exitcode) { systask_exit(NULL, exitcode); }

void system_exit_error(const char* title, const char* message,
const char* footer) {
systask_exit_error(NULL, title, message, footer);
void system_exit_error_ex(const char* title, size_t title_len,
const char* message, size_t message_len,
const char* footer, size_t footer_len) {
systask_exit_error(NULL, title, title_len, message, message_len, footer,
footer_len);
}

void system_exit_fatal(const char* message, const char* file, int line) {
systask_exit_fatal(NULL, message, file, line);
void system_exit_fatal_ex(const char* message, size_t message_len,
const char* file, size_t file_len, int line) {
systask_exit_fatal(NULL, message, message_len, file, file_len, line);
}

#endif // KERNEL_MODE

#ifndef HardFault_IRQn
#define HardFault_IRQn (-13) // not defined in stm32lib/cmsis/stm32429xx.h
#endif

#ifdef STM32U5
const char* system_fault_message(const system_fault_t* fault) {
switch (fault->irqn) {
case HardFault_IRQn:
return "(HF)";
case MemoryManagement_IRQn:
return "(MM)";
case BusFault_IRQn:
return "(BF)";
case UsageFault_IRQn:
return (fault->cfsr & SCB_CFSR_STKOF_Msk) ? "(SO)" : "(UF)";
case SecureFault_IRQn:
return "(SF)";
case GTZC_IRQn:
return "(IA)";
case NonMaskableInt_IRQn:
return "(CS)";
default:
return "(FAULT)";
}
}
#else // STM32U5
const char* system_fault_message(const system_fault_t* fault) {
switch (fault->irqn) {
case HardFault_IRQn:
return "(HF)";
case MemoryManagement_IRQn:
return (fault->sp < fault->sp_lim) ? "(SO)" : "(MM)";
case BusFault_IRQn:
return "(BF)";
case UsageFault_IRQn:
return "(UF)";
case NonMaskableInt_IRQn:
return "(CS)";
default:
return "(FAULT)";
}
}
#endif // STM32U5

__attribute__((used)) static void emergency_reset(void) {
// TODO: reset peripherals (at least DMA, DMA2D)

Expand Down Expand Up @@ -308,3 +271,60 @@ __attribute((naked, no_stack_protector)) void system_emergency_rescue(
: // no clobber
);
}

#endif // KERNEL_MODE

#ifdef STM32U5
const char* system_fault_message(const system_fault_t* fault) {
switch (fault->irqn) {
case HardFault_IRQn:
return "(HF)";
case MemoryManagement_IRQn:
return "(MM)";
case BusFault_IRQn:
return "(BF)";
case UsageFault_IRQn:
return (fault->cfsr & SCB_CFSR_STKOF_Msk) ? "(SO)" : "(UF)";
case SecureFault_IRQn:
return "(SF)";
case GTZC_IRQn:
return "(IA)";
case NonMaskableInt_IRQn:
return "(CS)";
default:
return "(FAULT)";
}
}
#else // STM32U5
const char* system_fault_message(const system_fault_t* fault) {
switch (fault->irqn) {
case HardFault_IRQn:
return "(HF)";
case MemoryManagement_IRQn:
return (fault->sp < fault->sp_lim) ? "(SO)" : "(MM)";
case BusFault_IRQn:
return "(BF)";
case UsageFault_IRQn:
return "(UF)";
case NonMaskableInt_IRQn:
return "(CS)";
default:
return "(FAULT)";
}
}
#endif // STM32U5

void system_exit_error(const char* title, const char* message,
const char* footer) {
size_t title_len = title != NULL ? strlen(title) : 0;
size_t message_len = message != NULL ? strlen(message) : 0;
size_t footer_len = footer != NULL ? strlen(footer) : 0;
system_exit_error_ex(title, title_len, message, message_len, footer,
footer_len);
}

void system_exit_fatal(const char* message, const char* file, int line) {
size_t message_len = message != NULL ? strlen(message) : 0;
size_t file_len = file != NULL ? strlen(file) : 0;
system_exit_fatal_ex(message, message_len, file, file_len, line);
}
8 changes: 5 additions & 3 deletions core/embed/trezorhal/systask.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,15 @@ void systask_exit(systask_t* task, int exit_code);
// Terminates the task with an error message
//
// (see `systask_exit()` for more details)
void systask_exit_error(systask_t* task, const char* title, const char* message,
const char* footer);
void systask_exit_error(systask_t* task, const char* title, size_t title_len,
const char* message, size_t message_len,
const char* footer, size_t footer_len);

// Terminates the task with a fatal error message
//
// (see `systask_exit()` for more details)
void systask_exit_fatal(systask_t* task, const char* message, const char* file,
void systask_exit_fatal(systask_t* task, const char* message,
size_t message_len, const char* file, size_t file_len,
int line);

#endif // KERNEL_MODE
Expand Down
Loading

0 comments on commit 7f7193a

Please sign in to comment.