fusee/exo: add ability to disable user exception handlers

please do not use this
yellows8 needs it to debug am, 99% of use cases want them on
This commit is contained in:
Michael Scire 2019-05-10 03:50:25 -07:00
parent 03a425a579
commit bb6cc6532b
8 changed files with 45 additions and 14 deletions

View file

@ -8,6 +8,9 @@ stage2_entrypoint = 0xF0000000
; Note: Disabling debugmode will cause parts of ams.tma to not work, in the future. ; Note: Disabling debugmode will cause parts of ams.tma to not work, in the future.
debugmode = 1 debugmode = 1
debugmode_user = 0 debugmode_user = 0
; Note: Disabling usermode exception handlers will cause atmosphere to not fail gracefully under error conditions.
; Support will not be provided to users who disable these. If you do not know what you are doing, leave them on.
disable_user_exception_handlers = 0
[stratosphere] [stratosphere]
; To force-enable nogc, add nogc = 1 ; To force-enable nogc, add nogc = 1

View file

@ -37,6 +37,7 @@
static bool g_hiz_mode_enabled = false; static bool g_hiz_mode_enabled = false;
static bool g_debugmode_override_user = false, g_debugmode_override_priv = false; static bool g_debugmode_override_user = false, g_debugmode_override_priv = false;
static bool g_enable_usermode_exception_handlers = true;
uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) { uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
switch (item) { switch (item) {
@ -163,6 +164,10 @@ void configitem_set_debugmode_override(bool user, bool priv) {
g_debugmode_override_priv = priv; g_debugmode_override_priv = priv;
} }
void configitem_disable_usermode_exception_handlers(void) {
g_enable_usermode_exception_handlers = false;
}
uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue) { uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue) {
uint32_t result = 0; uint32_t result = 0;
switch (item) { switch (item) {
@ -213,8 +218,10 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
case CONFIGITEM_KERNELCONFIGURATION: case CONFIGITEM_KERNELCONFIGURATION:
{ {
uint64_t config = bootconfig_get_kernel_configuration(); uint64_t config = bootconfig_get_kernel_configuration();
/* Always enable usermode exception handlers. */ /* Enable usermode exception handlers by default. */
if (g_enable_usermode_exception_handlers) {
config |= KERNELCONFIGFLAG_ENABLE_USER_EXCEPTION_HANDLERS; config |= KERNELCONFIGFLAG_ENABLE_USER_EXCEPTION_HANDLERS;
}
*p_outvalue = config; *p_outvalue = config;
} }
break; break;

View file

@ -60,6 +60,7 @@ bool configitem_is_hiz_mode_enabled(void);
bool configitem_is_debugmode_priv(void); bool configitem_is_debugmode_priv(void);
void configitem_set_debugmode_override(bool user, bool priv); void configitem_set_debugmode_override(bool user, bool priv);
void configitem_disable_usermode_exception_handlers(void);
void configitem_set_hiz_mode_enabled(bool enabled); void configitem_set_hiz_mode_enabled(bool enabled);
uint64_t configitem_get_hardware_type(void); uint64_t configitem_get_hardware_type(void);

View file

@ -75,3 +75,11 @@ unsigned int exosphere_should_override_debugmode_user(void) {
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_IS_DEBUGMODE_USER); return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_IS_DEBUGMODE_USER);
} }
unsigned int exosphere_should_disable_usermode_exception_handlers(void) {
if (!g_has_loaded_config) {
generic_panic();
}
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS);
}

View file

@ -35,10 +35,11 @@
/* Exosphere config in DRAM shares physical/virtual mapping. */ /* Exosphere config in DRAM shares physical/virtual mapping. */
#define MAILBOX_EXOSPHERE_CONFIG_PHYS MAILBOX_EXOSPHERE_CONFIG #define MAILBOX_EXOSPHERE_CONFIG_PHYS MAILBOX_EXOSPHERE_CONFIG
#define EXOSPHERE_FLAGS_DEFAULT 0x00000000
#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u) #define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u)
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u) #define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u) #define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
#define EXOSPHERE_FLAGS_DEFAULT (EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV)
typedef struct { typedef struct {
unsigned int magic; unsigned int magic;
@ -52,6 +53,7 @@ unsigned int exosphere_get_target_firmware(void);
unsigned int exosphere_should_perform_620_keygen(void); unsigned int exosphere_should_perform_620_keygen(void);
unsigned int exosphere_should_override_debugmode_priv(void); unsigned int exosphere_should_override_debugmode_priv(void);
unsigned int exosphere_should_override_debugmode_user(void); unsigned int exosphere_should_override_debugmode_user(void);
unsigned int exosphere_should_disable_usermode_exception_handlers(void);
static inline unsigned int exosphere_get_target_firmware_for_init(void) { static inline unsigned int exosphere_get_target_firmware_for_init(void) {
const unsigned int magic = MAILBOX_EXOSPHERE_CONFIG_PHYS.magic; const unsigned int magic = MAILBOX_EXOSPHERE_CONFIG_PHYS.magic;

View file

@ -538,6 +538,9 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
/* Load Exosphere-specific config. */ /* Load Exosphere-specific config. */
exosphere_load_config(); exosphere_load_config();
configitem_set_debugmode_override(exosphere_should_override_debugmode_user() != 0, exosphere_should_override_debugmode_priv() != 0); configitem_set_debugmode_override(exosphere_should_override_debugmode_user() != 0, exosphere_should_override_debugmode_priv() != 0);
if (exosphere_should_disable_usermode_exception_handlers() != 0) {
configitem_disable_usermode_exception_handlers();
}
/* Setup the Security Engine. */ /* Setup the Security Engine. */
setup_se(); setup_se();

View file

@ -24,10 +24,11 @@
/* "EXO0" */ /* "EXO0" */
#define MAGIC_EXOSPHERE_CONFIG (0x304F5845) #define MAGIC_EXOSPHERE_CONFIG (0x304F5845)
#define EXOSPHERE_FLAGS_DEFAULT 0x00000000
#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u) #define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u)
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u) #define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u) #define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
#define EXOSPHERE_FLAGS_DEFAULT (EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV)
typedef struct { typedef struct {
unsigned int magic; unsigned int magic;
@ -41,5 +42,6 @@ typedef struct {
#define EXOSPHERE_TARGETFW_KEY "target_firmware" #define EXOSPHERE_TARGETFW_KEY "target_firmware"
#define EXOSPHERE_DEBUGMODE_PRIV_KEY "debugmode" #define EXOSPHERE_DEBUGMODE_PRIV_KEY "debugmode"
#define EXOSPHERE_DEBUGMODE_USER_KEY "debugmode_user" #define EXOSPHERE_DEBUGMODE_USER_KEY "debugmode_user"
#define EXOSPHERE_DISABLE_USERMODE_EXCEPTION_HANDLERS_KEY "disable_user_exception_handlers"
#endif #endif

View file

@ -106,22 +106,27 @@ static int exosphere_ini_handler(void *user, const char *section, const char *na
if (strcmp(section, "exosphere") == 0) { if (strcmp(section, "exosphere") == 0) {
if (strcmp(name, EXOSPHERE_TARGETFW_KEY) == 0) { if (strcmp(name, EXOSPHERE_TARGETFW_KEY) == 0) {
sscanf(value, "%d", &exo_cfg->target_firmware); sscanf(value, "%d", &exo_cfg->target_firmware);
} } else if (strcmp(name, EXOSPHERE_DEBUGMODE_PRIV_KEY) == 0) {
if (strcmp(name, EXOSPHERE_DEBUGMODE_PRIV_KEY) == 0) {
sscanf(value, "%d", &tmp); sscanf(value, "%d", &tmp);
if (tmp) { if (tmp) {
exo_cfg->flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV; exo_cfg->flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV;
} else { } else {
exo_cfg->flags &= ~(EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV); exo_cfg->flags &= ~(EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV);
} }
} } else if (strcmp(name, EXOSPHERE_DEBUGMODE_USER_KEY) == 0) {
if (strcmp(name, EXOSPHERE_DEBUGMODE_USER_KEY) == 0) {
sscanf(value, "%d", &tmp); sscanf(value, "%d", &tmp);
if (tmp) { if (tmp) {
exo_cfg->flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_USER; exo_cfg->flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_USER;
} else { } else {
exo_cfg->flags &= ~(EXOSPHERE_FLAG_IS_DEBUGMODE_USER); exo_cfg->flags &= ~(EXOSPHERE_FLAG_IS_DEBUGMODE_USER);
} }
} else if (strcmp(name, EXOSPHERE_DISABLE_USERMODE_EXCEPTION_HANDLERS_KEY) == 0) {
sscanf(value, "%d", &tmp);
if (tmp) {
exo_cfg->flags |= EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS;
} else {
exo_cfg->flags &= ~(EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS);
}
} else { } else {
return 0; return 0;
} }