mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-19 12:58:13 +00:00
refactor(core): improve and simplify error handling
[no changelog]
This commit is contained in:
parent
ac1a25fc21
commit
5fc3c6e617
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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); }
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
123
core/embed/lib/error_handling.c
Normal file
123
core/embed/lib/error_handling.c
Normal 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");
|
||||
}
|
57
core/embed/lib/error_handling.h
Normal file
57
core/embed/lib/error_handling.h
Normal 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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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> {
|
||||
|
@ -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]
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
@ -49,3 +49,5 @@ mod _new_rendering {
|
||||
}
|
||||
|
||||
pub use _new_rendering::render_on_display;
|
||||
|
||||
pub use bumps::unlock_bumps_on_failure;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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)");
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)");
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user