diff --git a/common/defaults/BCT.ini b/common/defaults/BCT.ini index b74c19725..c55aa0f35 100644 --- a/common/defaults/BCT.ini +++ b/common/defaults/BCT.ini @@ -8,6 +8,9 @@ stage2_entrypoint = 0xF0000000 ; Note: Disabling debugmode will cause parts of ams.tma to not work, in the future. debugmode = 1 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] ; To force-enable nogc, add nogc = 1 diff --git a/exosphere/src/configitem.c b/exosphere/src/configitem.c index 3db892230..b53421d6f 100644 --- a/exosphere/src/configitem.c +++ b/exosphere/src/configitem.c @@ -37,6 +37,7 @@ static bool g_hiz_mode_enabled = 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) { switch (item) { @@ -163,6 +164,10 @@ void configitem_set_debugmode_override(bool user, bool 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 result = 0; switch (item) { @@ -213,8 +218,10 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue) case CONFIGITEM_KERNELCONFIGURATION: { uint64_t config = bootconfig_get_kernel_configuration(); - /* Always enable usermode exception handlers. */ - config |= KERNELCONFIGFLAG_ENABLE_USER_EXCEPTION_HANDLERS; + /* Enable usermode exception handlers by default. */ + if (g_enable_usermode_exception_handlers) { + config |= KERNELCONFIGFLAG_ENABLE_USER_EXCEPTION_HANDLERS; + } *p_outvalue = config; } break; diff --git a/exosphere/src/configitem.h b/exosphere/src/configitem.h index bcf5ca72c..b9600c833 100644 --- a/exosphere/src/configitem.h +++ b/exosphere/src/configitem.h @@ -60,6 +60,7 @@ bool configitem_is_hiz_mode_enabled(void); bool configitem_is_debugmode_priv(void); void configitem_set_debugmode_override(bool user, bool priv); +void configitem_disable_usermode_exception_handlers(void); void configitem_set_hiz_mode_enabled(bool enabled); uint64_t configitem_get_hardware_type(void); diff --git a/exosphere/src/exocfg.c b/exosphere/src/exocfg.c index 80689d684..533de8beb 100644 --- a/exosphere/src/exocfg.c +++ b/exosphere/src/exocfg.c @@ -75,3 +75,11 @@ unsigned int exosphere_should_override_debugmode_user(void) { 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); +} diff --git a/exosphere/src/exocfg.h b/exosphere/src/exocfg.h index 74f0443e4..ba53be403 100644 --- a/exosphere/src/exocfg.h +++ b/exosphere/src/exocfg.h @@ -35,10 +35,11 @@ /* Exosphere config in DRAM shares physical/virtual mapping. */ #define MAILBOX_EXOSPHERE_CONFIG_PHYS MAILBOX_EXOSPHERE_CONFIG -#define EXOSPHERE_FLAGS_DEFAULT 0x00000000 -#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u) -#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u) -#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u) +#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u) +#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u) +#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 { 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_override_debugmode_priv(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) { const unsigned int magic = MAILBOX_EXOSPHERE_CONFIG_PHYS.magic; diff --git a/exosphere/src/package2.c b/exosphere/src/package2.c index c62781b95..66d8828fe 100644 --- a/exosphere/src/package2.c +++ b/exosphere/src/package2.c @@ -538,6 +538,9 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) { /* Load Exosphere-specific config. */ exosphere_load_config(); 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_se(); diff --git a/fusee/fusee-secondary/src/exocfg.h b/fusee/fusee-secondary/src/exocfg.h index fd42c1336..e8054ec9d 100644 --- a/fusee/fusee-secondary/src/exocfg.h +++ b/fusee/fusee-secondary/src/exocfg.h @@ -24,10 +24,11 @@ /* "EXO0" */ #define MAGIC_EXOSPHERE_CONFIG (0x304F5845) -#define EXOSPHERE_FLAGS_DEFAULT 0x00000000 -#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u) -#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u) -#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u) +#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u) +#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u) +#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 { unsigned int magic; @@ -41,5 +42,6 @@ typedef struct { #define EXOSPHERE_TARGETFW_KEY "target_firmware" #define EXOSPHERE_DEBUGMODE_PRIV_KEY "debugmode" #define EXOSPHERE_DEBUGMODE_USER_KEY "debugmode_user" +#define EXOSPHERE_DISABLE_USERMODE_EXCEPTION_HANDLERS_KEY "disable_user_exception_handlers" #endif \ No newline at end of file diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index 7b52157e3..f7badf580 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -106,22 +106,27 @@ static int exosphere_ini_handler(void *user, const char *section, const char *na if (strcmp(section, "exosphere") == 0) { if (strcmp(name, EXOSPHERE_TARGETFW_KEY) == 0) { sscanf(value, "%d", &exo_cfg->target_firmware); - } - if (strcmp(name, EXOSPHERE_DEBUGMODE_PRIV_KEY) == 0) { + } else if (strcmp(name, EXOSPHERE_DEBUGMODE_PRIV_KEY) == 0) { sscanf(value, "%d", &tmp); if (tmp) { exo_cfg->flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV; } else { exo_cfg->flags &= ~(EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV); } - } - if (strcmp(name, EXOSPHERE_DEBUGMODE_USER_KEY) == 0) { + } else if (strcmp(name, EXOSPHERE_DEBUGMODE_USER_KEY) == 0) { sscanf(value, "%d", &tmp); if (tmp) { exo_cfg->flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_USER; } else { 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 { return 0; }