1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-23 14:58:09 +00:00

refactor(core): improve and simplify error handling

[no changelog]
This commit is contained in:
cepetr 2024-06-10 16:57:59 +02:00 committed by cepetr
parent ac1a25fc21
commit 5fc3c6e617
36 changed files with 291 additions and 476 deletions

View File

@ -68,6 +68,7 @@ CPPPATH_MOD += [
SOURCE_MOD += [
'embed/lib/colors.c',
'embed/lib/display_utils.c',
'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gfx_color.c',

View File

@ -107,6 +107,7 @@ SOURCE_MOD += [
'embed/lib/buffers.c',
'embed/lib/colors.c',
'embed/lib/display_utils.c',
'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gfx_color.c',

View File

@ -98,6 +98,7 @@ SOURCE_MOD += [
'embed/lib/colors.c',
'embed/lib/display_draw.c',
'embed/lib/display_utils.c',
'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/image.c',

View File

@ -102,6 +102,7 @@ SOURCE_MOD += [
'embed/lib/buffers.c',
'embed/lib/colors.c',
'embed/lib/display_utils.c',
'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gfx_color.c',
@ -109,6 +110,7 @@ SOURCE_MOD += [
'embed/lib/gfx_bitblt_rgb565.c',
'embed/lib/gfx_bitblt_rgba8888.c',
'embed/lib/image.c',
'embed/lib/mini_printf.c',
'embed/lib/terminal.c',
'embed/lib/touch.c',
'embed/lib/unit_variant.c',
@ -144,10 +146,10 @@ SOURCE_BOOTLOADER = [
SOURCE_TREZORHAL = [
'embed/trezorhal/unix/boot_args.c',
'embed/trezorhal/unix/common.c',
'embed/trezorhal/unix/fault_handlers.c',
'embed/trezorhal/unix/flash.c',
'embed/trezorhal/unix/flash_otp.c',
'embed/trezorhal/unix/common.c',
'embed/trezorhal/unix/touch/touch.c',
'embed/trezorhal/unix/rng.c',
'embed/trezorhal/unix/usb.c',

View File

@ -226,6 +226,7 @@ SOURCE_MOD += [
'embed/lib/buffers.c',
'embed/lib/colors.c',
'embed/lib/display_utils.c',
'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gfx_color.c',

View File

@ -102,6 +102,7 @@ SOURCE_MOD += [
'embed/lib/colors.c',
'embed/lib/display_draw.c',
'embed/lib/display_utils.c',
'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/image.c',

View File

@ -74,6 +74,7 @@ SOURCE_MOD += [
'embed/lib/colors.c',
'embed/lib/display_draw.c',
'embed/lib/display_utils.c',
'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/image.c',

View File

@ -232,6 +232,7 @@ SOURCE_MOD += [
'embed/lib/buffers.c',
'embed/lib/colors.c',
'embed/lib/display_utils.c',
'embed/lib/error_handling.c',
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gfx_color.c',
@ -239,6 +240,7 @@ SOURCE_MOD += [
'embed/lib/gfx_bitblt_rgba8888.c',
'embed/lib/gfx_bitblt_mono8.c',
'embed/lib/image.c',
'embed/lib/mini_printf.c',
'embed/lib/terminal.c',
'embed/lib/translations.c',
'embed/lib/unit_variant.c',

View File

@ -88,27 +88,6 @@ bool load_firmware(const char *filename, uint8_t *hash) {
return true;
}
__attribute__((noreturn)) void display_error_and_die(const char *message,
const char *title,
const char *footer) {
if (footer == NULL) {
footer = "PLEASE VISIT\nTREZOR.IO/RSOD";
}
if (title == NULL) {
title = "INTERNAL ERROR";
}
display_init();
display_backlight(180);
screen_fatal_error_rust(title, message, footer);
#if USE_TOUCH
printf("Click screen to exit.\n");
#elif USE_BUTTON
printf("Press both buttons to exit.\n");
#endif
ui_click();
exit(0);
}
__attribute__((noreturn)) int main(int argc, char **argv) {
display_init();
flash_init();
@ -175,7 +154,7 @@ __attribute__((noreturn)) int main(int argc, char **argv) {
} else {
message = "No message specified";
}
display_error_and_die(message, title, footer);
error_shutdown_ex(title, message, footer);
}
// write variant to OTP
@ -198,18 +177,13 @@ __attribute__((noreturn)) void jump_to(void *addr) {
if (storage_is_erased) {
printf("STORAGE WAS ERASED\n");
screen_fatal_error_rust("BOOTLOADER EXIT", "Jumped to firmware",
"STORAGE WAS ERASED");
error_shutdown_ex("BOOTLOADER EXIT", "Jumped to firmware",
"STORAGE WAS ERASED");
} else {
printf("storage was retained\n");
screen_fatal_error_rust("BOOTLOADER EXIT", "Jumped to firmware",
"STORAGE WAS RETAINED");
error_shutdown_ex("BOOTLOADER EXIT", "Jumped to firmware",
"STORAGE WAS RETAINED");
}
display_backlight(180);
hal_delay(3000);
exit(0);
}
void ensure_compatible_settings(void) {}
void main_clean_exit(int code) { exit(code); }

View File

@ -192,7 +192,8 @@ static usb_result_t bootloader_usb_loop(const vendor_header *const vhdr,
r = process_msg_FirmwareUpload(USB_IFACE_NUM, msg_size, buf);
if (r < 0 && r != UPLOAD_ERR_USER_ABORT) { // error, but not user abort
if (r == UPLOAD_ERR_BOOTLOADER_LOCKED) {
secret_show_install_restricted_screen();
// This function does not return
show_install_restricted_screen();
} else {
ui_screen_fail();
}
@ -291,9 +292,7 @@ static void check_bootloader_version(void) {
#endif
void failed_jump_to_firmware(void) {
error_shutdown("INTERNAL ERROR", "(glitch)");
}
void failed_jump_to_firmware(void) { error_shutdown("(glitch)"); }
void real_jump_to_firmware(void) {
const image_header *hdr = NULL;

View File

@ -213,8 +213,9 @@ static void _usb_webusb_read_retry(uint8_t iface_num, uint8_t *buf) {
continue;
} else {
// error
error_shutdown("USB ERROR",
"Error reading from USB. Try different USB cable.");
error_shutdown_ex("USB ERROR",
"Error reading from USB. Try different USB cable.",
NULL);
}
}
return; // success

View File

@ -200,8 +200,9 @@ static void _usb_webusb_read_retry(uint8_t iface_num, uint8_t *buf) {
// only timeout => let's try again
} else {
// error
error_shutdown("USB ERROR",
"Error reading from USB. Try different USB cable.");
error_shutdown_ex("USB ERROR",
"Error reading from USB. Try different USB cable.",
NULL);
}
}
return; // success

View File

@ -161,8 +161,7 @@ void secp256k1_default_illegal_callback_fn(const char *str, void *data) {
void secp256k1_default_error_callback_fn(const char *str, void *data) {
(void)data;
__fatal_error(NULL, str, __FILE__, __LINE__, __func__);
return;
error_shutdown(str);
}
#endif

View File

@ -274,7 +274,7 @@ int main(void) {
mp_deinit();
// Python code shouldn't ever exit, avoid black screen if it does
error_shutdown("INTERNAL ERROR", "(PE)");
error_shutdown("(PE)");
return 0;
}
@ -282,7 +282,7 @@ int main(void) {
// MicroPython default exception handler
void __attribute__((noreturn)) nlr_jump_fail(void *val) {
error_shutdown("INTERNAL ERROR", "(UE)");
error_shutdown("(UE)");
}
// MicroPython builtin stubs

View File

@ -0,0 +1,123 @@
/*
* 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 <stddef.h>
#include "common.h"
#include "display.h"
#include "error_handling.h"
#include "mini_printf.h"
#ifdef FANCY_FATAL_ERROR
#include "rust_ui.h"
#else
#include "terminal.h"
#endif
#ifdef RGB16
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
#else
#define COLOR_FATAL_ERROR COLOR_BLACK
#endif
void __attribute__((noreturn))
error_shutdown_ex(const char *title, const char *message, const char *footer) {
if (title == NULL) {
title = "INTERNAL ERROR";
}
if (footer == NULL) {
footer = "PLEASE VISIT\nTREZOR.IO/RSOD";
}
#ifdef FANCY_FATAL_ERROR
error_shutdown_rust(title, message, footer);
#else
display_orientation(0);
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
term_printf("%s\n", title);
if (message) {
term_printf("%s\n", message);
}
term_printf("\n%s\n", footer);
display_backlight(255);
trezor_shutdown();
#endif
}
void __attribute__((noreturn)) error_shutdown(const char *message) {
error_shutdown_ex(NULL, message, NULL);
}
void __attribute__((noreturn))
__fatal_error(const char *expr, const char *msg, const char *file, int line,
const char *func) {
#ifdef FANCY_FATAL_ERROR
char buf[256] = {0};
mini_snprintf(buf, sizeof(buf), "%s: %d", file, line);
error_shutdown(msg != NULL ? msg : buf);
#else
display_orientation(0);
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
term_printf("\nINTERNAL ERROR:\n");
if (expr) {
term_printf("expr: %s\n", expr);
}
if (msg) {
term_printf("msg : %s\n", msg);
}
if (file) {
term_printf("file: %s:%d\n", file, line);
}
if (func) {
term_printf("func: %s\n", func);
}
#ifdef SCM_REVISION
const uint8_t *rev = (const uint8_t *)SCM_REVISION;
term_printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
rev[4]);
#endif
term_printf("\nPlease contact Trezor support.\n");
display_backlight(255);
trezor_shutdown();
#endif
}
#ifndef NDEBUG
void __assert_func(const char *file, int line, const char *func,
const char *expr) {
__fatal_error(expr, "assert failed", file, line, func);
}
#endif
void __attribute__((noreturn)) show_wipe_code_screen(void) {
error_shutdown_ex("WIPE CODE ENTERED",
"All data has been erased from the device",
"PLEASE RECONNECT\nTHE DEVICE");
}
void __attribute__((noreturn)) show_pin_too_many_screen(void) {
error_shutdown_ex("TOO MANY PIN ATTEMPTS",
"All data has been erased from the device",
"PLEASE RECONNECT\nTHE DEVICE");
}
void __attribute__((noreturn)) show_install_restricted_screen(void) {
error_shutdown_ex("INSTALL RESTRICTED",
"Installation of custom firmware is currently restricted.",
"Please visit\ntrezor.io/bootloader");
}

View File

@ -0,0 +1,57 @@
/*
* 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/>.
*/
#ifndef LIB_ERROR_HANDLING_H
#define LIB_ERROR_HANDLING_H
// Shows an error message and shuts down the device.
//
// If the title is NULL, it will be set to "INTERNAL ERROR".
// If the message is NULL, it will be ignored.
// If the footer is NULL, it will be set to "PLEASE VISIT TREZOR.IO/RSOD".
void __attribute__((noreturn))
error_shutdown_ex(const char *title, const char *message, const char *footer);
// Shows an error message and shuts down the device.
//
// Same as `error_shutdown_ex()` but with a default header and footer.
void __attribute__((noreturn)) error_shutdown(const char *message);
// Do not use this function directly, use the `ensure()` macro instead.
void __attribute__((noreturn))
__fatal_error(const char *expr, const char *msg, const char *file, int line,
const char *func);
// Checks for an expression and if it is false, shows an error message
// and shuts down the device.
#define ensure(expr, msg) \
(((expr) == sectrue) \
? (void)0 \
: __fatal_error(#expr, msg, __FILE__, __LINE__, __func__))
// Shows WIPE CODE ENTERED screeen and shuts down the device.
void __attribute__((noreturn)) show_wipe_code_screen(void);
// Shows TOO MANY PIN ATTEMPTS screen and shuts down the device.
void __attribute__((noreturn)) show_pin_too_many_screen(void);
// Shows INSTALL RESTRICTED screen and shuts down the device.
void __attribute__((noreturn)) show_install_restricted_screen(void);
#endif // LIB_ERRORS_H

View File

@ -180,12 +180,18 @@ void term_print(const char *text, int textlen) {
void term_printf(const char *fmt, ...) {
if (!strchr(fmt, '%')) {
term_print(fmt, strlen(fmt));
#ifdef TREZOR_EMULATOR
printf("%s", fmt);
#endif
} else {
va_list va;
va_start(va, fmt);
char buf[256] = {0};
int len = mini_vsnprintf(buf, sizeof(buf), fmt, va);
term_print(buf, len);
#ifdef TREZOR_EMULATOR
vprintf(fmt, va);
#endif
va_end(va);
}
}

View File

@ -1,7 +1,8 @@
#include "common.h"
void screen_fatal_error_rust(const char* title, const char* msg,
const char* footer);
__attribute__((noreturn)) void error_shutdown_rust(const char* title,
const char* msg,
const char* footer);
void screen_boot_stage_2(void);

View File

@ -5,24 +5,34 @@ mod ffi {
}
}
use crate::ui::ui_features::{ModelUI, UIFeaturesCommon};
use crate::ui::{
shape,
ui_features::{ModelUI, UIFeaturesCommon},
};
fn shutdown() -> ! {
unsafe { ffi::trezor_shutdown() }
}
#[cfg(feature = "bootloader")]
pub fn __fatal_error(_expr: &str, _msg: &str, _file: &str, _line: u32, _func: &str) -> ! {
ModelUI::screen_fatal_error("BL.rs", "BL.rs", "PLEASE VISIT\nTREZOR.IO/RSOD");
/// Shows an error message and shuts down the device.
pub fn error_shutdown(title: &str, msg: &str, footer: &str) -> ! {
// SAFETY:
// This is the only situation we are allowed use this function
// to allow nested calls to `run_with_bumps`/`render_on_display`,
// because after the error message is displayed, the application will
// shut down.
unsafe { shape::unlock_bumps_on_failure() };
ModelUI::screen_fatal_error(title, msg, footer);
ModelUI::backlight_on();
shutdown()
}
#[cfg(not(feature = "bootloader"))]
/// Shows an error message on the screen and shuts down the device.
/// In debug mode, also prints the error message to the console.
#[inline(never)] // saves few kilobytes of flash
pub fn __fatal_error(_expr: &str, msg: &str, _file: &str, _line: u32, _func: &str) -> ! {
ModelUI::screen_fatal_error("INTERNAL_ERROR", msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
ModelUI::backlight_on();
shutdown()
error_shutdown("INTERNAL_ERROR", msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
}
pub trait UnwrapOrFatalError<T> {

View File

@ -10,19 +10,19 @@ use crate::ui::{
geometry::{Alignment2D, Point},
};
use crate::ui::util::from_c_str;
use crate::{trezorhal::fatal_error, ui::util::from_c_str};
#[no_mangle]
extern "C" fn screen_fatal_error_rust(
extern "C" fn error_shutdown_rust(
title: *const cty::c_char,
msg: *const cty::c_char,
footer: *const cty::c_char,
) {
) -> ! {
let title = unsafe { from_c_str(title) }.unwrap_or("");
let msg = unsafe { from_c_str(msg) }.unwrap_or("");
let footer = unsafe { from_c_str(footer) }.unwrap_or("");
ModelUI::screen_fatal_error(title, msg, footer);
fatal_error::error_shutdown(title, msg, footer)
}
#[no_mangle]

View File

@ -22,6 +22,9 @@ pub const BUMP_A_SIZE: usize = DrawingCache::get_bump_a_size() + SHAPE_MEM_SIZE;
/// Size of `bump_b` memory that must be accessible by DMA
pub const BUMP_B_SIZE: usize = DrawingCache::get_bump_b_size();
//
static mut LOCKED: bool = false;
/// Runs a user-defined function with two bump allocators.
///
/// The function is passed two bump allocators, `bump_a` and `bump_b`, which
@ -32,8 +35,6 @@ pub fn run_with_bumps<F>(func: F)
where
F: for<'a> FnOnce(&'a mut Bump<[u8; BUMP_A_SIZE]>, &'a mut Bump<[u8; BUMP_B_SIZE]>),
{
static mut LOCKED: bool = false;
// SAFETY:
// The application is single-threaded, so we can safely use a
// static variable as a lock against nested calls.
@ -64,3 +65,20 @@ where
LOCKED = false;
};
}
// This function enables nested invocations of `run_with_bumps()`,
// which is necessary when the application needs to display a
// fatal error message and subsequently terminate.
//
// SAFETY:
// This function must be invoked exclusively in failure scenarios
// where the application is required to display a fatal error
// message and then shut down. It is safe to call this function
// only under these specific conditions.
pub unsafe fn unlock_bumps_on_failure() {
// The application is single-threaded, so we can safely use a
// static variable as a lock against nested calls.
unsafe {
LOCKED = false;
};
}

View File

@ -49,3 +49,5 @@ mod _new_rendering {
}
pub use _new_rendering::render_on_display;
pub use bumps::unlock_bumps_on_failure;

View File

@ -28,7 +28,7 @@ pub use canvas::{
};
pub use circle::Circle;
pub use corner_highlight::CornerHighlight;
pub use display::{render_on_canvas, render_on_display};
pub use display::{render_on_canvas, render_on_display, unlock_bumps_on_failure};
#[cfg(feature = "ui_jpeg_decoder")]
pub use jpeg::JpegImage;
pub use qrcode::QrImage;

View File

@ -24,6 +24,7 @@
#include <stdint.h>
#include "secbool.h"
#include "error_handling.h"
#include "platform.h"
#ifndef MIN_8bits
@ -53,20 +54,6 @@
void __attribute__((noreturn)) trezor_shutdown(void);
void __attribute__((noreturn))
__fatal_error(const char *expr, const char *msg, const char *file, int line,
const char *func);
void __attribute__((noreturn))
error_shutdown(const char *label, const char *msg);
void show_wipe_code_screen(void);
void show_pin_too_many_screen(void);
#define ensure(expr, msg) \
(((expr) == sectrue) \
? (void)0 \
: __fatal_error(#expr, msg, __FILE__, __LINE__, __func__))
void hal_delay(uint32_t ms);
uint32_t hal_ticks_ms();
void hal_delay_us(uint16_t delay_us);

View File

@ -60,7 +60,3 @@ void secret_bhk_regenerate(void);
// Disables access to the secret storage until next reset, if possible
// This function is called by the bootloader before starting the firmware
void secret_prepare_fw(secbool allow_run_with_secret, secbool trust_all);
// Shows a screen informing the user that installation of custom firmware is
// currently restricted
void secret_show_install_restricted_screen(void);

View File

@ -22,9 +22,6 @@
#include "common.h"
#include "model.h"
#define handle_fault(msg) \
(__fatal_error("Fault detected", msg, __FILE__, __LINE__, __func__))
static uint32_t board_name = 0;
static struct BoardloaderVersion boardloader_version;
@ -53,7 +50,7 @@ void parse_boardloader_capabilities() {
pos += 2;
if (pos + length > end) {
handle_fault("Bad capabilities format.");
error_shutdown("Bad capabilities format");
}
switch (tag) {

View File

@ -24,29 +24,18 @@
#include "common.h"
#include "display.h"
#include "model.h"
#include "terminal.h"
#ifdef FANCY_FATAL_ERROR
#include "rust_ui.h"
#endif
#include "flash_otp.h"
#include "platform.h"
#include "rand.h"
#include "supervise.h"
#include "mini_printf.h"
#include "stm32f4xx_ll_utils.h"
#ifdef TREZOR_MODEL_T
#include "backlight_pwm.h"
#endif
#ifdef RGB16
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
#else
#define COLOR_FATAL_ERROR COLOR_BLACK
#endif
uint32_t systick_val_copy = 0;
// from util.s
@ -65,92 +54,6 @@ void __attribute__((noreturn)) trezor_shutdown(void) {
;
}
void __attribute__((noreturn))
error_uni(const char *label, const char *msg, const char *footer) {
display_orientation(0);
#ifdef FANCY_FATAL_ERROR
screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
#else
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
if (label) {
term_printf("%s\n", label);
}
if (msg) {
term_printf("%s\n", msg);
}
if (footer) {
term_printf("\n%s\n", footer);
}
#endif
display_backlight(255);
trezor_shutdown();
}
void __attribute__((noreturn))
__fatal_error(const char *expr, const char *msg, const char *file, int line,
const char *func) {
display_orientation(0);
display_backlight(255);
#ifdef FANCY_FATAL_ERROR
char buf[256] = {0};
mini_snprintf(buf, sizeof(buf), "%s: %d", file, line);
screen_fatal_error_rust("INTERNAL ERROR", msg != NULL ? msg : buf,
"PLEASE VISIT\nTREZOR.IO/RSOD");
#else
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
term_printf("\nINTERNAL ERROR:\n");
if (expr) {
term_printf("expr: %s\n", expr);
}
if (msg) {
term_printf("msg : %s\n", msg);
}
if (file) {
term_printf("file: %s:%d\n", file, line);
}
if (func) {
term_printf("func: %s\n", func);
}
#ifdef SCM_REVISION
const uint8_t *rev = (const uint8_t *)SCM_REVISION;
term_printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
rev[4]);
#endif
term_printf("\nPlease contact Trezor support.\n");
#endif
trezor_shutdown();
}
void __attribute__((noreturn))
error_shutdown(const char *label, const char *msg) {
display_orientation(0);
#ifdef FANCY_FATAL_ERROR
screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
#else
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
if (label) {
term_printf("%s\n", label);
}
if (msg) {
term_printf("%s\n", msg);
}
term_printf("\nPLEASE VISIT TREZOR.IO/RSOD\n");
#endif
display_backlight(255);
trezor_shutdown();
}
#ifndef NDEBUG
void __assert_func(const char *file, int line, const char *func,
const char *expr) {
__fatal_error(expr, "assert failed", file, line, func);
}
#endif
void hal_delay(uint32_t ms) { HAL_Delay(ms); }
uint32_t hal_ticks_ms() { return HAL_GetTick(); }
void hal_delay_us(uint16_t delay_us) {
@ -185,7 +88,7 @@ void clear_otg_hs_memory(void) {
uint32_t __stack_chk_guard = 0;
void __attribute__((noreturn)) __stack_chk_fail(void) {
error_shutdown("INTERNAL ERROR", "(SS)");
error_shutdown("(SS)");
}
uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
@ -230,15 +133,6 @@ void ensure_compatible_settings(void) {
#endif
}
void show_wipe_code_screen(void) {
error_uni("WIPE CODE ENTERED", "All data has been erased from the device",
"PLEASE RECONNECT\nTHE DEVICE");
}
void show_pin_too_many_screen(void) {
error_uni("TOO MANY PIN ATTEMPTS", "All data has been erased from the device",
"PLEASE RECONNECT\nTHE DEVICE");
}
void invalidate_firmware(void) {
// erase start of the firmware (metadata) -> invalidate FW
ensure(flash_unlock_write(), NULL);

View File

@ -5,19 +5,19 @@ void fault_handlers_init(void) {
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("(HF)"); }
void MemManage_Handler_MM(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
void MemManage_Handler_MM(void) { error_shutdown("(MM)"); }
void MemManage_Handler_SO(void) { error_shutdown("INTERNAL ERROR", "(SO)"); }
void MemManage_Handler_SO(void) { error_shutdown("(SO)"); }
void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); }
void BusFault_Handler(void) { error_shutdown("(BF)"); }
void UsageFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(UF)"); }
void UsageFault_Handler(void) { error_shutdown("(UF)"); }
void NMI_Handler(void) {
// Clock Security System triggered NMI
if ((RCC->CIR & RCC_CIR_CSSF) != 0) {
error_shutdown("INTERNAL ERROR", "(CS)");
error_shutdown("(CS)");
}
}

View File

@ -98,21 +98,11 @@ secbool secret_optiga_get(uint8_t dest[SECRET_OPTIGA_KEY_LEN]) {
return secret_read(dest, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN);
}
void secret_show_install_restricted_screen(void) {
#ifdef FANCY_FATAL_ERROR
display_clear();
screen_fatal_error_rust(
"INSTALL RESTRICTED",
"Installation of custom firmware is currently restricted.",
"Please visit\ntrezor.io/bootloader");
#endif
}
void secret_prepare_fw(secbool allow_run_with_secret, secbool _trust_all) {
#ifdef USE_OPTIGA
if (sectrue != allow_run_with_secret && sectrue != secret_wiped()) {
secret_show_install_restricted_screen();
trezor_shutdown();
// This function does not return
show_install_restricted_screen();
}
#endif
}

View File

@ -23,26 +23,15 @@
#include "common.h"
#include "display.h"
#include "secret.h"
#include "terminal.h"
#ifdef FANCY_FATAL_ERROR
#include "rust_ui.h"
#endif
#include "flash_otp.h"
#include "model.h"
#include "platform.h"
#include "rand.h"
#include "secret.h"
#include "supervise.h"
#include "mini_printf.h"
#include "stm32u5xx_ll_utils.h"
#ifdef RGB16
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
#else
#define COLOR_FATAL_ERROR COLOR_BLACK
#endif
uint32_t systick_val_copy = 0;
// from util.s
@ -66,91 +55,6 @@ void __attribute__((noreturn)) trezor_shutdown(void) {
;
}
void __attribute__((noreturn))
error_uni(const char *label, const char *msg, const char *footer) {
display_orientation(0);
#ifdef FANCY_FATAL_ERROR
screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
#else
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
if (label) {
term_printf("%s\n", label);
}
if (msg) {
term_printf("%s\n", msg);
}
if (footer) {
term_printf("\n%s\n", footer);
}
#endif
display_backlight(255);
trezor_shutdown();
}
void __attribute__((noreturn))
__fatal_error(const char *expr, const char *msg, const char *file, int line,
const char *func) {
display_orientation(0);
display_backlight(255);
#ifdef FANCY_FATAL_ERROR
char buf[256] = {0};
mini_snprintf(buf, sizeof(buf), "%s: %d", file, line);
screen_fatal_error_rust("INTERNAL ERROR", msg != NULL ? msg : buf,
"PLEASE VISIT\nTREZOR.IO/RSOD");
#else
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
term_printf("\nINTERNAL ERROR:\n");
if (expr) {
term_printf("expr: %s\n", expr);
}
if (msg) {
term_printf("msg : %s\n", msg);
}
if (file) {
term_printf("file: %s:%d\n", file, line);
}
if (func) {
term_printf("func: %s\n", func);
}
#ifdef SCM_REVISION
const uint8_t *rev = (const uint8_t *)SCM_REVISION;
term_printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
rev[4]);
#endif
term_printf("\nPlease contact Trezor support.\n");
#endif
trezor_shutdown();
}
void __attribute__((noreturn))
error_shutdown(const char *label, const char *msg) {
display_orientation(0);
#ifdef FANCY_FATAL_ERROR
screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
#else
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
if (label) {
term_printf("%s\n", label);
}
if (msg) {
term_printf("%s\n", msg);
}
term_printf("\nPLEASE VISIT TREZOR.IO/RSOD\n");
#endif
display_backlight(255);
trezor_shutdown();
}
#ifndef NDEBUG
void __assert_func(const char *file, int line, const char *func,
const char *expr) {
__fatal_error(expr, "assert failed", file, line, func);
}
#endif
void hal_delay(uint32_t ms) { HAL_Delay(ms); }
uint32_t hal_ticks_ms() { return HAL_GetTick(); }
void hal_delay_us(uint16_t delay_us) {
@ -168,7 +72,7 @@ void hal_delay_us(uint16_t delay_us) {
uint32_t __stack_chk_guard = 0;
void __attribute__((noreturn)) __stack_chk_fail(void) {
error_shutdown("INTERNAL ERROR", "(SS)");
error_shutdown("(SS)");
}
uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
@ -202,15 +106,6 @@ void collect_hw_entropy(void) {
// where this setting might be unknown
void ensure_compatible_settings(void) {}
void show_wipe_code_screen(void) {
error_uni("WIPE CODE ENTERED", "All data has been erased from the device",
"PLEASE RECONNECT\nTHE DEVICE");
}
void show_pin_too_many_screen(void) {
error_uni("TOO MANY PIN ATTEMPTS", "All data has been erased from the device",
"PLEASE RECONNECT\nTHE DEVICE");
}
void invalidate_firmware(void) {
// on stm32u5, we need to disable the instruction cache before erasing the
// firmware - otherwise, the write check will fail

View File

@ -5,11 +5,11 @@ void fault_handlers_init(void) {
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("(HF)"); }
void MemManage_Handler(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
void MemManage_Handler(void) { error_shutdown("(MM)"); }
void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); }
void BusFault_Handler(void) { error_shutdown("(BF)"); }
void UsageFault_Handler(void) {
if (SCB->CFSR & SCB_CFSR_STKOF_Msk) {
@ -17,20 +17,20 @@ void UsageFault_Handler(void) {
extern uint8_t _estack; // linker script symbol
// Fix stack pointer
__set_MSP((uint32_t)&_estack);
error_shutdown("INTERNAL ERROR", "(SO)");
error_shutdown("(SO)");
} else {
// Other error
error_shutdown("INTERNAL ERROR", "(UF)");
error_shutdown("(UF)");
}
}
void SecureFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(SF)"); }
void SecureFault_Handler(void) { error_shutdown("(SF)"); }
void GTZC_IRQHandler(void) { error_shutdown("INTERNAL ERROR", "(IA)"); }
void GTZC_IRQHandler(void) { error_shutdown("(IA)"); }
void NMI_Handler(void) {
// Clock Security System triggered NMI
if ((RCC->CIFR & RCC_CIFR_CSSF) != 0) {
error_shutdown("INTERNAL ERROR", "(CS)");
error_shutdown("(CS)");
}
}

View File

@ -239,12 +239,6 @@ void secret_erase(void) {
ensure(flash_area_erase(&SECRET_AREA, NULL), "secret erase");
}
void secret_show_install_restricted_screen(void) {
// this should never happen on U5
__fatal_error("INTERNAL ERROR", "Install restricted", __FILE__, __LINE__,
__func__);
}
void secret_prepare_fw(secbool allow_run_with_secret, secbool trust_all) {
/**
* The BHK is copied to the backup registers, which are accessible by the SAES

View File

@ -238,7 +238,7 @@ void TAMP_IRQHandler(void) {
TAMP->SCR = sr;
#ifdef BOARDLOADER
error_shutdown("INTERNAL TAMPER", "");
error_shutdown_ex("INTERNAL TAMPER", NULL, NULL);
#else
const char* reason = "UNKNOWN";
if (sr & TAMP_SR_TAMP1F) {
@ -268,6 +268,6 @@ void TAMP_IRQHandler(void) {
} else if (sr & TAMP_SR_ITAMP13F) {
reason = "ANALOG WDG3";
}
error_shutdown("INTERNAL TAMPER", reason);
error_shutdown_ex("INTERNAL TAMPER", reason, NULL);
#endif
}

View File

@ -26,128 +26,16 @@
#include "common.h"
#include "display.h"
#ifdef FANCY_FATAL_ERROR
#include "rust_ui.h"
#endif
#include "memzero.h"
extern void main_clean_exit(int);
void __attribute__((noreturn)) trezor_shutdown(void) {
display_finish_actions();
printf("SHUTDOWN\n");
main_clean_exit(3);
for (;;)
;
}
#ifdef RGB16
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
#else
// black on monochromatic displays
#define COLOR_FATAL_ERROR 0x0000
#endif
void __attribute__((noreturn))
error_uni(const char *label, const char *msg, const char *footer) {
display_orientation(0);
#ifdef FANCY_FATAL_ERROR
screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
#else
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
if (label) {
term_printf("%s\n", label);
}
if (msg) {
term_printf("%s\n", msg);
}
if (footer) {
term_printf("\n%s\n", footer);
}
#endif
display_backlight(255);
// Wait some time to let the user see the displayed
// message before shutting down
hal_delay(3000);
trezor_shutdown();
}
void __attribute__((noreturn))
__fatal_error(const char *expr, const char *msg, const char *file, int line,
const char *func) {
display_orientation(0);
display_backlight(255);
#ifdef FANCY_FATAL_ERROR
if (msg == NULL) {
msg = "Unknown error";
char buf[256] = {0};
snprintf(buf, sizeof(buf), "%s: %d", file, line);
screen_fatal_error_rust("INTERNAL ERROR", buf,
"PLEASE VISIT\nTREZOR.IO/RSOD");
} else {
screen_fatal_error_rust("INTERNAL ERROR", msg,
"PLEASE VISIT\nTREZOR.IO/RSOD");
}
#else
term_set_color(COLOR_WHITE, COLOR_FATAL_ERROR);
term_printf("\nINTERNAL ERROR:\n");
printf("\nINTERNAL ERROR:\n");
if (expr) {
term_printf("expr: %s\n", expr);
printf("expr: %s\n", expr);
}
if (msg) {
term_printf("msg : %s\n", msg);
printf("msg : %s\n", msg);
}
if (file) {
term_printf("file: %s:%d\n", file, line);
printf("file: %s:%d\n", file, line);
}
if (func) {
term_printf("func: %s\n", func);
printf("func: %s\n", func);
}
#ifdef SCM_REVISION
const uint8_t *rev = (const uint8_t *)SCM_REVISION;
term_printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
rev[4]);
printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
rev[4]);
#endif
term_printf("\n\n\nHint:\nIsn't the emulator already running?\n");
printf("Hint:\nIsn't the emulator already running?\n");
#endif
hal_delay(3000);
trezor_shutdown();
}
void __attribute__((noreturn))
error_shutdown(const char *label, const char *msg) {
#ifdef FANCY_FATAL_ERROR
screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
#else
display_clear();
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_FATAL_ERROR);
int y = 32;
if (label) {
display_text(8, y, label, -1, FONT_NORMAL, COLOR_WHITE, COLOR_FATAL_ERROR);
printf("%s\n", label);
y += 32;
}
if (msg) {
display_text(8, y, msg, -1, FONT_NORMAL, COLOR_WHITE, COLOR_FATAL_ERROR);
printf("%s\n", msg);
y += 32;
}
y += 32;
display_text(8, y, "Please unplug the device.", -1, FONT_NORMAL, COLOR_WHITE,
COLOR_FATAL_ERROR);
printf("\nPlease unplug the device.\n");
#endif
display_backlight(255);
hal_delay(5000);
exit(4);
exit(3);
}
void hal_delay(uint32_t ms) { usleep(1000 * ms); }
@ -161,7 +49,7 @@ uint32_t hal_ticks_ms() {
static int SDLCALL emulator_event_filter(void *userdata, SDL_Event *event) {
switch (event->type) {
case SDL_QUIT:
trezor_shutdown();
exit(3);
return 0;
case SDL_KEYUP:
if (event->key.repeat) {
@ -169,7 +57,7 @@ static int SDLCALL emulator_event_filter(void *userdata, SDL_Event *event) {
}
switch (event->key.keysym.sym) {
case SDLK_ESCAPE:
trezor_shutdown();
exit(3);
return 0;
case SDLK_p:
display_save("emu");
@ -188,12 +76,3 @@ void emulator_poll_events(void) {
uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
void collect_hw_entropy(void) { memzero(HW_ENTROPY_DATA, HW_ENTROPY_LEN); }
void show_wipe_code_screen(void) {
error_uni("WIPE CODE ENTERED", "All data has been erased from the device",
"PLEASE RECONNECT\nTHE DEVICE");
}
void show_pin_too_many_screen(void) {
error_uni("TOO MANY PIN ATTEMPTS", "All data has been erased from the device",
"PLEASE RECONNECT\nTHE DEVICE");
}

View File

@ -27,20 +27,12 @@
#include <time.h>
#include <unistd.h>
#include "error_handling.h"
#include "profile.h"
#include "usb.h"
#include "memzero.h"
void __attribute__((noreturn))
__fatal_error(const char *expr, const char *msg, const char *file, int line,
const char *func);
#define ensure(expr, msg) \
(((expr) == sectrue) \
? (void)0 \
: __fatal_error(#expr, msg, __FILE__, __LINE__, __func__))
// emulator opens UDP server and emulates HID/WebUSB interfaces
// gracefully ignores all other USB interfaces

View File

@ -407,16 +407,6 @@ STATIC void set_sys_argv(char *argv[], int argc, int start_arg) {
}
}
void main_clean_exit(int status) {
fflush(stdout);
fflush(stderr);
// sys.exit is disabled, so raise a SystemExit exception directly
nlr_raise(mp_obj_new_exception_arg1(&mp_type_SystemExit,
MP_OBJ_NEW_SMALL_INT(status)));
// the above shouldn't return, but make sure we exit just in case
exit(status);
}
#ifdef _WIN32
#define PATHLIST_SEP_CHAR ';'
#else