diff --git a/src/trusted/service_runtime/build.scons b/src/trusted/service_runtime/build.scons index 70833a48ed..a2728cf1f5 100644 --- a/src/trusted/service_runtime/build.scons +++ b/src/trusted/service_runtime/build.scons @@ -652,10 +652,7 @@ if env.Bit('windows') and env.Bit('build_x86_64'): ]) node = env.CommandTest('patch_ntdll_test.out', command=[test_prog], declares_exit_status=True) - # This is broken in opt but not dbg mode. The difference is - # /MT vs. /MTd. - env.AddNodeToTestSuite(node, ['small_tests'], 'run_patch_ntdll_test', - is_broken=True) + env.AddNodeToTestSuite(node, ['small_tests'], 'run_patch_ntdll_test') intercept_test_prog = env.ComponentProgram( 'ntdll_intercept_test', 'win/exception_patch/intercept_test.c', diff --git a/src/trusted/service_runtime/linux/nacl_bootstrap.c b/src/trusted/service_runtime/linux/nacl_bootstrap.c index 4cf204cb1e..70010cb101 100644 --- a/src/trusted/service_runtime/linux/nacl_bootstrap.c +++ b/src/trusted/service_runtime/linux/nacl_bootstrap.c @@ -156,7 +156,7 @@ __attribute__((noreturn)) static void fail(const char *filename, sys_writev(2, iov, niov); sys_exit_group(2); - while (1) *(volatile int *) 0 = 0; /* Crash. */ + while (1) *(volatile int *) 4 = 0; /* Crash. */ } diff --git a/src/trusted/service_runtime/win/exception_patch/exit_fast.S b/src/trusted/service_runtime/win/exception_patch/exit_fast.S index 1a765fc772..a6634e6b86 100644 --- a/src/trusted/service_runtime/win/exception_patch/exit_fast.S +++ b/src/trusted/service_runtime/win/exception_patch/exit_fast.S @@ -10,6 +10,12 @@ * This routine terminates the process safely and is patched onto * NTDLL's KiUserExceptionDispatcher. * + * For Windows 8+ there is the new __fastfail intrinsic (int 0x29) to + * immediately terminate the process. On an old Windows where that is + * not available, the unrecognized interrupt should be treated like + * a generic exception and the next two paragraphs apply (except that + * the faulting instruction is INT instead of HLT). + * * To terminate the process safely, we set %rsp to zero and then * execute a HLT instruction. If we do not set %rsp to zero, the HLT * instruction will cause the kernel to rerun the fault handler after @@ -28,6 +34,8 @@ .globl IDENTIFIER(NaCl_exception_dispatcher_exit_fast) IDENTIFIER(NaCl_exception_dispatcher_exit_fast): xor %rsp, %rsp - hlt + mov $0x6c43614e, %rcx + int $0x29 + hlt /* should be unreachable even on old Windows */ .globl IDENTIFIER(NaCl_exception_dispatcher_exit_fast_end) IDENTIFIER(NaCl_exception_dispatcher_exit_fast_end): diff --git a/src/trusted/service_runtime/win/exception_patch/intercept_test.c b/src/trusted/service_runtime/win/exception_patch/intercept_test.c index ad1aac67f2..7a87d15b7a 100644 --- a/src/trusted/service_runtime/win/exception_patch/intercept_test.c +++ b/src/trusted/service_runtime/win/exception_patch/intercept_test.c @@ -31,7 +31,7 @@ static void TryCrash(void) { void *handlerHandle = AddVectoredExceptionHandler(/*First=*/0, TheHandler); CHECK(handlerHandle); continueLabel = &&cleanup; - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; cleanup: continueLabel = NULL; printf("Caught exception OK\n"); @@ -42,7 +42,7 @@ static void TryCrash(void) { static void TryCrash(void) { __try { - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; } __except (EXCEPTION_EXECUTE_HANDLER) { printf("Caught exception OK\n"); } diff --git a/src/trusted/service_runtime/win/exception_patch/ntdll_test.c b/src/trusted/service_runtime/win/exception_patch/ntdll_test.c index f5662a5de9..879a3f7b1b 100644 --- a/src/trusted/service_runtime/win/exception_patch/ntdll_test.c +++ b/src/trusted/service_runtime/win/exception_patch/ntdll_test.c @@ -18,11 +18,21 @@ static int g_counter = 0; void CauseFault(void) { - *(int *) 0 = 0; + *(volatile int *) 4 = 0; } void ReplacementHandler(void) { - printf("In replacement handler (%i)\n", g_counter++); + if (++g_counter > 5) { + volatile unsigned x = 0; + /* Arrived here more times than expected. Time out the test to show what is + happening and make sure it fails */ + while (1) { + ++x; + } + } + + puts("In replacement handler"); + if (g_counter < 5) { /* * Cause a fault to demonstrate that ReplacementHandler() gets @@ -35,7 +45,8 @@ void ReplacementHandler(void) { */ void (*exit_fast)(void) = (void (*)(void)) NaCl_exception_dispatcher_exit_fast; - fprintf(stderr, "** intended_exit_status=untrusted_segfault\n"); + // fast fail exception code: 0xC0000409 + fputs("** intended_exit_status=3221226505", stderr); exit_fast(); } } diff --git a/tests/debug_stub/debug_stub_test.py b/tests/debug_stub/debug_stub_test.py index 6c8f0d6467..43393aee6c 100644 --- a/tests/debug_stub/debug_stub_test.py +++ b/tests/debug_stub/debug_stub_test.py @@ -15,7 +15,7 @@ if sys.platform == 'win32': - RETURNCODE_KILL = -9 + RETURNCODE_KILL = -9 & 0xffffffff else: RETURNCODE_KILL = -9 & 0xff diff --git a/tests/debug_stub/nacl.scons b/tests/debug_stub/nacl.scons index d0639d1392..c858de3268 100644 --- a/tests/debug_stub/nacl.scons +++ b/tests/debug_stub/nacl.scons @@ -30,8 +30,7 @@ if env.GetEmulator(): # qualification tests because they fail under qemu-arm. sel_ldr_command = [env.GetEmulator()] + sel_ldr_command + ['-Q'] -is_broken = (not env.Bit('nacl_static_link') or env.GetSelLdr() is None or - env.Bit('host_windows')) +is_broken = not env.Bit('nacl_static_link') or env.GetSelLdr() is None if env.Bit('build_arm') or env.Bit('build_mips32'): # Use the system's 'nm' tool. The NaCl toolchain will not be @@ -54,7 +53,7 @@ node = env.CommandTest( extra_deps=[env.File('gdb_rsp.py')], # Don't run the host Python through qemu-arm. direct_emulation=False, - size='medium') + size='huge' if env.Bit('host_windows') else 'medium') env.AddNodeToTestSuite(node, ['medium_tests', 'nonpexe_tests'], 'run_debug_stub_test', is_broken=is_broken) env.TestBindsFixedTcpPort(node) diff --git a/tests/exception_test/exception_crash_test.c b/tests/exception_test/exception_crash_test.c index cf57abd7ed..e571634012 100644 --- a/tests/exception_test/exception_crash_test.c +++ b/tests/exception_test/exception_crash_test.c @@ -36,7 +36,7 @@ void test_bad_handler(void) { assert(rc == 0); fprintf(stderr, "** intended_exit_status=untrusted_segfault\n"); /* Cause crash. */ - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; } @@ -155,7 +155,7 @@ void test_stack_in_rwdata(void) { assert(rc == 0); fprintf(stderr, "** intended_exit_status=1\n"); /* Cause crash. */ - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; } @@ -172,7 +172,7 @@ void test_stack_in_rodata(void) { assert(rc == 0); fprintf(stderr, "** intended_exit_status=unwritable_exception_stack\n"); /* Cause crash. */ - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; } @@ -211,7 +211,7 @@ void test_stack_in_code(void) { assert(rc == 0); fprintf(stderr, "** intended_exit_status=unwritable_exception_stack\n"); /* Cause crash. */ - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; } diff --git a/tests/minnacl/minimal_test_guest.c b/tests/minnacl/minimal_test_guest.c index 8bc8804784..ab92aeb098 100644 --- a/tests/minnacl/minimal_test_guest.c +++ b/tests/minnacl/minimal_test_guest.c @@ -14,7 +14,7 @@ static void SimpleAbort(void) { while (1) { /* Exit by causing a crash. */ - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; } } diff --git a/tests/nonsfi/sigaction_test.cc b/tests/nonsfi/sigaction_test.cc index bc7bfa7654..27f0738c82 100644 --- a/tests/nonsfi/sigaction_test.cc +++ b/tests/nonsfi/sigaction_test.cc @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) { rc = setjmp(g_jmp_buf); if (rc == 0) { /* Crash. */ - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; _exit(1); /* Shouldn't reach here. */ } diff --git a/tests/nonsfi/signal_test.cc b/tests/nonsfi/signal_test.cc index 00e5ec9e8e..e6353cf480 100644 --- a/tests/nonsfi/signal_test.cc +++ b/tests/nonsfi/signal_test.cc @@ -29,7 +29,7 @@ int main(int argc, char *argv[]) { int rc = setjmp(g_jmp_buf); if (rc == 0) { /* Crash. */ - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; _exit(1); /* Shouldn't reach here. */ } diff --git a/tests/performance/perf_test_exceptions.cc b/tests/performance/perf_test_exceptions.cc index f2d2a152dc..1c5891311f 100644 --- a/tests/performance/perf_test_exceptions.cc +++ b/tests/performance/perf_test_exceptions.cc @@ -26,7 +26,7 @@ class TestCatchingFault : public PerfTest { if (!setjmp(return_jmp_buf_)) { // Cause crash. for (;;) - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; } } diff --git a/tests/signal_handler/crash_test.c b/tests/signal_handler/crash_test.c index 6f62a8b48b..5ffc94675e 100644 --- a/tests/signal_handler/crash_test.c +++ b/tests/signal_handler/crash_test.c @@ -13,7 +13,7 @@ int main(void) { least on ARM) and generates an illegal instruction, which generates SIGILL instead of SIGSEGV, and LLVM also optimises away the rest of the function. */ - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; fprintf(stderr, "[CRASH_TEST] FAIL: Survived crash attempt\n"); return 1; } diff --git a/tests/trusted_crash/osx_crash_filter/crash_filter_test.c b/tests/trusted_crash/osx_crash_filter/crash_filter_test.c index 93ce13e8ba..8e84780bfe 100644 --- a/tests/trusted_crash/osx_crash_filter/crash_filter_test.c +++ b/tests/trusted_crash/osx_crash_filter/crash_filter_test.c @@ -122,7 +122,7 @@ int main(int argc, char **argv) { g_expect_untrusted = 0; RegisterExceptionHandler(); /* Cause a crash. */ - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; } if (argc != 3) { diff --git a/tests/trusted_crash/osx_crash_forwarding/mach_crash_forwarding_test.c b/tests/trusted_crash/osx_crash_forwarding/mach_crash_forwarding_test.c index cfebb83cb9..f5dbba28a0 100644 --- a/tests/trusted_crash/osx_crash_forwarding/mach_crash_forwarding_test.c +++ b/tests/trusted_crash/osx_crash_forwarding/mach_crash_forwarding_test.c @@ -129,7 +129,7 @@ int main(int argc, char **argv) { if (argc == 2 && strcmp(argv[1], "early_trusted") == 0) { g_expect_crash = 1; /* Cause a crash. */ - *(volatile int *) 0 = 0; + *(volatile int *) 4 = 0; } if (argc != 3) {