| // Copyright Microsoft and CHERIoT Contributors. |
| // SPDX-License-Identifier: MIT |
| |
| #define TEST_NAME "Crash recovery (main runner)" |
| #include "crash_recovery.h" |
| #include <cheri.hh> |
| #include <errno.h> |
| |
| int crashes = 0; |
| |
| extern "C" enum ErrorRecoveryBehaviour |
| compartment_error_handler(struct ErrorState *frame, size_t mcause, size_t mtval) |
| { |
| debug_log("Test saw error for PCC {}", frame->pcc); |
| debug_log("Error cause: {}, mtval: {}", mcause, mtval); |
| if (mcause == 0x2) |
| { |
| debug_log("Test hit assertion failure, unwinding"); |
| return ErrorRecoveryBehaviour::ForceUnwind; |
| } |
| TEST((mcause == 0x1c) && (mtval == 0), |
| "mcause should be 0x1c (CHERI), is {}, mtval should be 0 (force " |
| "unwind), is {})", |
| mcause, |
| mtval); |
| crashes++; |
| debug_log("Resuming test at failure location"); |
| return ErrorRecoveryBehaviour::InstallContext; |
| } |
| |
| void test_crash_recovery() |
| { |
| debug_log("Calling crashy compartment indirectly"); |
| test_crash_recovery_outer(0); |
| check_stack(); |
| TEST(crashes == 0, "Ran crash handler for outer compartment"); |
| debug_log("Compartment with no error handler returned normally after " |
| "nested call crashed"); |
| |
| debug_log("Calling crashy compartment to fault and unwind"); |
| test_crash_recovery_inner(0); |
| check_stack(); |
| debug_log("Calling crashy compartment returned (crashes: {})", crashes); |
| TEST(crashes == 1, "Failed to notice crash"); |
| |
| debug_log("Calling crashy compartment to return normally"); |
| test_crash_recovery_inner(1); |
| check_stack(); |
| debug_log("Calling crashy compartment returned (crashes: {})", crashes); |
| TEST(crashes == 1, "Should not have crashed"); |
| debug_log("Returning normally from crash test"); |
| |
| debug_log("Calling crashy compartment to double fault and unwind"); |
| test_crash_recovery_inner(2); |
| check_stack(); |
| debug_log("Calling crashy compartment returned (crashes: {})", crashes); |
| TEST(crashes == 2, "Failed to notice crash"); |
| |
| debug_log( |
| "Calling crashy compartment to corrupt CSP in stack pointer and unwind"); |
| test_crash_recovery_inner(3); |
| check_stack(); |
| debug_log("Calling crashy compartment returned (crashes: {})", crashes); |
| TEST(crashes == 3, "Failed to notice crash"); |
| } |