diff --git a/cmake/define-test.cmake b/cmake/define-test.cmake index 6ab48231c..56cdec109 100644 --- a/cmake/define-test.cmake +++ b/cmake/define-test.cmake @@ -138,9 +138,11 @@ endfunction() # wrapped. # UNWRAPPED_LIBRARY_DIRS (optional) - extra library directories. # UNWRAPPED_LIBS (optional) - extra libraries that are not wrapped. +# CRITERION_TEST - If present, link against criterion and add the test to the +# cmake test infrastructure. function(define_test) # Parse options - set(options NEEDS_LD_WRAP NOT_IN_CHECK_IA2 NO_LIBS) + set(options NEEDS_LD_WRAP NOT_IN_CHECK_IA2 NO_LIBS CRITERION_TEST) set(oneValueArgs PKEY) set(multiValueArgs LIBS SRCS INCLUDE_DIR UNWRAPPED_INCLUDE_DIRS UNWRAPPED_LIBRARY_DIRS UNWRAPPED_LIBS) @@ -160,6 +162,14 @@ function(define_test) set(DEFINE_TEST_LIBS ${TEST_NAME}_lib) endif() + if (DEFINE_TEST_CRITERION_TEST) + list(APPEND DEFINE_TEST_UNWRAPPED_LIBS criterion) + if (NOT DEFINE_TEST_NOT_IN_CHECK_IA2) + add_test(${TEST_NAME} ${WRAPPED_MAIN}) + add_dependencies(check ${WRAPPED_MAIN}) + endif() + endif() + if(DEFINED DEFINE_TEST_INCLUDE_DIR) set(RELATIVE_INCLUDE_DIR ${DEFINE_TEST_INCLUDE_DIR}) else() diff --git a/rewriter/tests/CMakeLists.txt b/rewriter/tests/CMakeLists.txt index 51c38bd00..853bf957c 100644 --- a/rewriter/tests/CMakeLists.txt +++ b/rewriter/tests/CMakeLists.txt @@ -1,3 +1,5 @@ +include(CTest) + enable_testing() include("../../cmake/define-ia2-wrapper.cmake") @@ -22,13 +24,12 @@ set_target_properties(check-ia2 PROPERTIES FOLDER "tests") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -# Set up 'check' alias -add_custom_target(check) +# Set up 'check' target +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure) add_dependencies(check check-ia2) set_target_properties(check PROPERTIES FOLDER "tests") # add_subdirectory(ffmpeg) -add_subdirectory(function_allowlist) add_subdirectory(header_includes) add_subdirectory(heap_two_keys) # add_subdirectory(libusb) diff --git a/rewriter/tests/function_allowlist/CMakeLists.txt b/rewriter/tests/function_allowlist/CMakeLists.txt deleted file mode 100644 index 8b2d06a23..000000000 --- a/rewriter/tests/function_allowlist/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# Build the wrapped lib -define_shared_lib( - SRCS library.c -) - -# Build the test -define_test( - SRCS main.c - NEEDS_LD_WRAP -) - -# Build the wrapper lib -define_ia2_wrapper() diff --git a/rewriter/tests/function_allowlist/Output/function_allowlist.out b/rewriter/tests/function_allowlist/Output/function_allowlist.out deleted file mode 100644 index 52dac7dce..000000000 --- a/rewriter/tests/function_allowlist/Output/function_allowlist.out +++ /dev/null @@ -1,2 +0,0 @@ -foo -data is 30 diff --git a/rewriter/tests/function_allowlist/include/library.h b/rewriter/tests/function_allowlist/include/library.h deleted file mode 100644 index b65d1c7bf..000000000 --- a/rewriter/tests/function_allowlist/include/library.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -// This function does nothing, but should get wrapped -void foo(); - -// This function is not in the allowlist so it should not be wrapped -void defined_in_main(); diff --git a/rewriter/tests/function_allowlist/include/library.h.fns b/rewriter/tests/function_allowlist/include/library.h.fns deleted file mode 100644 index 257cc5642..000000000 --- a/rewriter/tests/function_allowlist/include/library.h.fns +++ /dev/null @@ -1 +0,0 @@ -foo diff --git a/rewriter/tests/function_allowlist/library.c b/rewriter/tests/function_allowlist/library.c deleted file mode 100644 index 791fa4347..000000000 --- a/rewriter/tests/function_allowlist/library.c +++ /dev/null @@ -1,8 +0,0 @@ -/* -RUN: cat function_allowlist_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s -*/ -#include "library.h" -#include - -// LINKARGS: --wrap=foo -void foo() { printf("foo\n"); } diff --git a/rewriter/tests/function_allowlist/main.c b/rewriter/tests/function_allowlist/main.c deleted file mode 100644 index 785e4acf2..000000000 --- a/rewriter/tests/function_allowlist/main.c +++ /dev/null @@ -1,20 +0,0 @@ -/* -RUN: cat function_allowlist_call_gates_0.ld | FileCheck --check-prefix=LINKARGS %s -RUN: %binary_dir/tests/function_allowlist/function_allowlist_main_wrapped | diff %S/Output/function_allowlist.out - -*/ -#include "library.h" -#include - -INIT_RUNTIME(1); -#define IA2_COMPARTMENT 1 -#include - -int data_in_main = 30; - -// LINKARGS: --wrap=defined_in_main -void defined_in_main() { printf("data is %d\n", data_in_main); } - -int main() { - foo(); - defined_in_main(); -} diff --git a/rewriter/tests/global_fn_ptr/CMakeLists.txt b/rewriter/tests/global_fn_ptr/CMakeLists.txt index 33141b014..133a6477d 100644 --- a/rewriter/tests/global_fn_ptr/CMakeLists.txt +++ b/rewriter/tests/global_fn_ptr/CMakeLists.txt @@ -7,6 +7,7 @@ define_shared_lib( define_test( SRCS main.c NEEDS_LD_WRAP + CRITERION_TEST ) # Build the wrapper lib diff --git a/rewriter/tests/global_fn_ptr/include/operations.h b/rewriter/tests/global_fn_ptr/include/operations.h index 3bc50da2e..d2ae659f5 100644 --- a/rewriter/tests/global_fn_ptr/include/operations.h +++ b/rewriter/tests/global_fn_ptr/include/operations.h @@ -1,6 +1,5 @@ /* RUN: cat %t.c.args | FileCheck --check-prefix=LINKARGS %s -RUN: %binary_dir/tests/global_fn_ptr/global_fn_ptr-main | diff %S/../Output/operations.out - */ #pragma once @@ -8,7 +7,7 @@ RUN: %binary_dir/tests/global_fn_ptr/global_fn_ptr-main | diff %S/../Output/oper #include // LINKARGS: --wrap=call_operations -void call_operations(void); +uint32_t call_operation(size_t i); // CHECK: typedef struct IA2_fnptr__ZTSPFjjjE WordFn; typedef uint32_t (*WordFn)(uint32_t, uint32_t); diff --git a/rewriter/tests/global_fn_ptr/main.c b/rewriter/tests/global_fn_ptr/main.c index 45be7d9fc..4cefe7767 100644 --- a/rewriter/tests/global_fn_ptr/main.c +++ b/rewriter/tests/global_fn_ptr/main.c @@ -1,9 +1,9 @@ /* RUN: sh -c 'if [ ! -s "global_fn_ptr_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' -RUN: %binary_dir/tests/global_fn_ptr/global_fn_ptr_main_wrapped | diff %S/Output/operations.out - */ #include "operations.h" #include +#include uint32_t add(uint32_t x, uint32_t y) { return x + y; } uint16_t sub(uint16_t x, uint16_t y) { return x - y; } @@ -39,6 +39,7 @@ Op operations[2] IA2_SHARED_DATA = { }, }; -int main() { - call_operations(); +Test(global_fn_ptr, main) { + cr_assert(call_operation(0) == 43312); + cr_assert(call_operation(1) == 461513047); } diff --git a/rewriter/tests/global_fn_ptr/operations.c b/rewriter/tests/global_fn_ptr/operations.c index 833fbe6a3..5a05012dd 100644 --- a/rewriter/tests/global_fn_ptr/operations.c +++ b/rewriter/tests/global_fn_ptr/operations.c @@ -2,18 +2,17 @@ RUN: cat global_fn_ptr_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ #include "operations.h" +#include #include extern Op operations[2]; -// LINKARGS: --wrap=call_operations -void call_operations(void) { - for (int i = 0; i < 2; i++) { - // TODO: Add a way to share strings between compartments - //printf("%s\n", operations[i].desc.data); - uint32_t x = 18923; - uint32_t y = 24389; - uint32_t res = operations[i].function(x, y); - printf("%d = f(%d, %d)\n", res, x, y); - } +// LINKARGS: --wrap=call_operation +uint32_t call_operation(size_t i) { + // TODO: Add a way to share strings between compartments + //printf("%s\n", operations[i].desc.data); + uint32_t x = 18923; + uint32_t y = 24389; + uint32_t res = operations[i].function(x, y); + return res; } diff --git a/rewriter/tests/header_includes/CMakeLists.txt b/rewriter/tests/header_includes/CMakeLists.txt index aa79f885f..efdd70e95 100644 --- a/rewriter/tests/header_includes/CMakeLists.txt +++ b/rewriter/tests/header_includes/CMakeLists.txt @@ -7,6 +7,7 @@ define_shared_lib( define_test( SRCS main.c NEEDS_LD_WRAP + CRITERION_TEST ) # Build the wrapper lib diff --git a/rewriter/tests/header_includes/liboption.c b/rewriter/tests/header_includes/liboption.c index 4af6209af..8e6e0df20 100644 --- a/rewriter/tests/header_includes/liboption.c +++ b/rewriter/tests/header_includes/liboption.c @@ -1,13 +1,13 @@ /* RUN: cat header_includes_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ -#include +#include #include "liboption.h" #include "types.h" // LINKARGS: --wrap=None Option None() { - printf("returning `None`\n"); + cr_log_info("returning `None`"); Option none = { .value = 0, .present = false, @@ -17,7 +17,7 @@ Option None() { // LINKARGS: --wrap=Some Option Some(int x) { - printf("returning `Some(%d)`\n", x); + cr_log_info("returning `Some(%d)`", x); Option opt = { .value = x, .present = true, diff --git a/rewriter/tests/header_includes/main.c b/rewriter/tests/header_includes/main.c index 56e796c15..98fcd0214 100644 --- a/rewriter/tests/header_includes/main.c +++ b/rewriter/tests/header_includes/main.c @@ -3,16 +3,17 @@ RUN: sh -c 'if [ ! -s "header_includes_call_gates_0.ld" ]; then echo "No link ar */ #include "liboption.h" #include "types.h" -#include +#include +#include #include INIT_RUNTIME(1); #define IA2_COMPARTMENT 1 #include -int main() { +Test(header_includes, main) { Option x = Some(3); Option none = None(); - printf("`x` has value %d\n", unwrap_or(x, -1)); - printf("`none` has no value %d\n", unwrap_or(none, -1)); + cr_assert_eq(unwrap_or(x, -1), 3); + cr_assert_eq(unwrap_or(none, -1), -1); } diff --git a/rewriter/tests/heap_two_keys/CMakeLists.txt b/rewriter/tests/heap_two_keys/CMakeLists.txt index 0fa58179c..cd48fcd62 100644 --- a/rewriter/tests/heap_two_keys/CMakeLists.txt +++ b/rewriter/tests/heap_two_keys/CMakeLists.txt @@ -11,6 +11,7 @@ define_test( PKEY 1 NEEDS_LD_WRAP INCLUDE_DIR include/plugin + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/heap_two_keys/main.c b/rewriter/tests/heap_two_keys/main.c index 4b14fbbb9..d007b998b 100644 --- a/rewriter/tests/heap_two_keys/main.c +++ b/rewriter/tests/heap_two_keys/main.c @@ -1,11 +1,9 @@ /* RUN: sh -c 'if [ ! -s "heap_two_keys_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' -RUN: %binary_dir/tests/heap_two_keys/heap_two_keys_main_wrapped 0 | diff %S/Output/clean_exit.out - -RUN: %binary_dir/tests/heap_two_keys/heap_two_keys_main_wrapped 1 | diff %S/Output/fault.out - -RUN: %binary_dir/tests/heap_two_keys/heap_two_keys_main_wrapped 2 | diff %S/Output/fault.out - -RUN: %binary_dir/tests/heap_two_keys/heap_two_keys_main_wrapped 3 | diff %S/Output/clean_exit.out - */ -#include +#include +#include +#include #include #include #include @@ -20,81 +18,45 @@ INIT_RUNTIME(2); #include // Test that the program can exit without error -int test_0() { - return 0; +Test(heap_two_keys, 0, .init = trigger_compartment_init) { } // Test that the main binary's heap can't be read -int test_1() { +Test(heap_two_keys, 1, .init = trigger_compartment_init) { uint32_t *x = (uint32_t *)malloc(sizeof(uint32_t)); if (!x) { - LOG("Failed to allocate memory on the heap"); - return -1; + cr_fatal("Failed to allocate memory on the heap"); } *x = 0x09431233; read_from_plugin_expect_fault((uint8_t*)x); free(x); // This test shouldn't return - return -1; + cr_fatal("Should have segfaulted but didn't"); } // Test that the main binary's heap can't be written to -int test_2() { +Test(heap_two_keys, 2, .init = trigger_compartment_init) { // This zeroes out the allocated memory uint8_t *x = (uint8_t *)calloc(sizeof(uint8_t), 12); if (!x) { - LOG("Failed to allocate memory on the heap"); - return -1; + cr_fatal("Failed to allocate memory on the heap"); } write_from_plugin_expect_fault(x, 12); free(x); // This test shouldn't return - return -1; + cr_fatal("Should have segfaulted but didn't"); } // Test that the main binary's shared data can be read -int test_3() { +Test(heap_two_keys, 3, .init = trigger_compartment_init) { uint16_t *x = (uint16_t *)shared_malloc(sizeof(uint16_t)); if (!x) { - LOG("Failed to allocate memory on the heap"); - return -1; + cr_fatal("Failed to allocate memory on the heap"); } *x = 0xffed; assert(read_from_plugin((uint8_t*)x) == 0xed); shared_free(x); - return 0; } // TODO: Add tests for free, realloc, the plugin's heap and reserving more than -// once from the gigacage (> 2MB in allocations) - -int main(int argc, char **argv) { - if (argc < 2) { - LOG("Run with an integer (0-3) as the first argument to select a test"); - return -1; - } - - // Call a no-op function to switch to this compartment's PKRU - trigger_compartment_init(); - - int test_num = *argv[1] - '0'; - - switch (test_num) { - case 0: { - return test_0(); - } - case 1: { - return test_1(); - } - case 2: { - return test_2(); - } - case 3: { - return test_3(); - } - default: { - LOG("Unknown test selected"); - return -1; - } - } -} +// once from the gigacage (> 2MB in allocations) \ No newline at end of file diff --git a/rewriter/tests/macro_attr/CMakeLists.txt b/rewriter/tests/macro_attr/CMakeLists.txt index 603ba8e87..668922de6 100644 --- a/rewriter/tests/macro_attr/CMakeLists.txt +++ b/rewriter/tests/macro_attr/CMakeLists.txt @@ -7,6 +7,7 @@ define_shared_lib( define_test( SRCS main.c NEEDS_LD_WRAP + CRITERION_TEST ) # Build the wrapper lib diff --git a/rewriter/tests/macro_attr/functions.c b/rewriter/tests/macro_attr/functions.c index c7311601f..ad84673b1 100644 --- a/rewriter/tests/macro_attr/functions.c +++ b/rewriter/tests/macro_attr/functions.c @@ -1,36 +1,36 @@ /* RUN: cat macro_attr_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ -#include +#include #include "functions.h" // LINKARGS: --wrap=f void f() { - printf("Called `f()`\n"); + cr_log_info("Called `f()`"); } // LINKARGS: --wrap=g void g() { - printf("Called `g()`\n"); + cr_log_info("Called `g()`"); } // TODO(src_rewriter_wip): this gets --wrap, but i don't think it should void h(CB cb) { - printf("Calling `cb(0)` from `h`\n"); + cr_log_info("Calling `cb(0)` from `h`"); cb(0); } // LINKARGS: --wrap=i void i() { - printf("Called `i()`\n"); + cr_log_info("Called `i()`"); } // LINKARGS: --wrap=j void j() { - printf("Called `j()`\n"); + cr_log_info("Called `j()`"); } // LINKARGS: --wrap=k void k() { - printf("Called `k()`\n"); + cr_log_info("Called `k()`"); } diff --git a/rewriter/tests/macro_attr/main.c b/rewriter/tests/macro_attr/main.c index d2e407d53..a23205163 100644 --- a/rewriter/tests/macro_attr/main.c +++ b/rewriter/tests/macro_attr/main.c @@ -3,12 +3,13 @@ RUN: sh -c 'if [ ! -s "macro_attr_call_gates_0.ld" ]; then echo "No link args as */ #include "functions.h" #include +#include INIT_RUNTIME(1); #define IA2_COMPARTMENT 1 #include -int main() { +Test(macro_attr, main) { f(); g(); i(); diff --git a/rewriter/tests/minimal/CMakeLists.txt b/rewriter/tests/minimal/CMakeLists.txt index e0dfe47b5..1893d27c1 100644 --- a/rewriter/tests/minimal/CMakeLists.txt +++ b/rewriter/tests/minimal/CMakeLists.txt @@ -5,6 +5,7 @@ define_shared_lib(SRCS minimal.c) define_test( SRCS main.c NEEDS_LD_WRAP + CRITERION_TEST ) # Build the wrapper lib diff --git a/rewriter/tests/minimal/main.c b/rewriter/tests/minimal/main.c index 2ee6e078d..c819e4016 100644 --- a/rewriter/tests/minimal/main.c +++ b/rewriter/tests/minimal/main.c @@ -1,6 +1,5 @@ /* RUN: sh -c 'if [ ! -s "minimal_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' -RUN: %binary_dir/tests/minimal/minimal_main_wrapped | diff %S/Output/minimal.out - RUN: readelf -lW %binary_dir/tests/minimal/minimal_main_wrapped | FileCheck --check-prefix=SEGMENTS %s */ @@ -8,6 +7,7 @@ RUN: readelf -lW %binary_dir/tests/minimal/minimal_main_wrapped | FileCheck --ch // SEGMENTS-COUNT-1: LOAD{{.*}}R E // SEGMENTS-NOT: LOAD{{.*}}R E +#include #include "minimal.h" #include @@ -15,6 +15,7 @@ INIT_RUNTIME(1); #define IA2_COMPARTMENT 1 #include -int main() { +Test(minimal, main) { + cr_log_info("Calling foo"); foo(); } diff --git a/rewriter/tests/minimal/minimal.c b/rewriter/tests/minimal/minimal.c index f337e159b..dca720e5f 100644 --- a/rewriter/tests/minimal/minimal.c +++ b/rewriter/tests/minimal/minimal.c @@ -3,21 +3,21 @@ RUN: cat minimal_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ #include "minimal.h" -#include +#include // LINKARGS: --wrap=arg1 void arg1(int x) { - printf("arg1\n"); + cr_log_info("arg1"); } // LINKARGS: --wrap=foo void foo() { - printf("foo\n"); + cr_log_info("foo"); } // LINKARGS: --wrap=return_val int return_val() { - printf("return_val\n"); + cr_log_info("return_val"); return 1; } diff --git a/rewriter/tests/mmap_loop/CMakeLists.txt b/rewriter/tests/mmap_loop/CMakeLists.txt index d45097fec..338ab3103 100644 --- a/rewriter/tests/mmap_loop/CMakeLists.txt +++ b/rewriter/tests/mmap_loop/CMakeLists.txt @@ -10,6 +10,7 @@ define_test( SRCS main.c PKEY 1 NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/mmap_loop/main.c b/rewriter/tests/mmap_loop/main.c index 08d6956f8..341a0ab8a 100644 --- a/rewriter/tests/mmap_loop/main.c +++ b/rewriter/tests/mmap_loop/main.c @@ -1,12 +1,12 @@ /* RUN: sh -c 'if [ ! -s "mmap_loop_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' -RUN: %binary_dir/tests/mmap_loop/mmap_loop_main_wrapped | diff %S/Output/mmap_loop.out - */ #include "mmap_loop.h" #include #include #include #include +#include #define IA2_DEFINE_TEST_HANDLER #include "test_fault_handler.h" @@ -19,8 +19,8 @@ INIT_RUNTIME(2); #define IA2_COMPARTMENT 1 #include -int main() { - puts("program started"); +Test(mmap_loop, main) { + cr_log_info("program started"); char *buf = malloc(4096); buf[0] = 'r'; @@ -28,17 +28,18 @@ int main() { char *lib_buf_malloc = lib_malloc_buf(4096); - puts("mmap buf"); + cr_log_info("mmap buf"); char *lib_buf_mmap = lib_mmap_buf(4096); free(buf); - /* syscall tracing should forbid us to unmap compartment 2's buffer */ + // syscall tracing should forbid us to unmap compartment 2's buffer + // this requires the track-memory-map runtime which isn't enabled in tests int res = munmap(lib_buf_mmap, 4096); if (res < 0) { perror("munmap"); + cr_log_info("Was not able to unmap memory in another compartment (as expected)"); + } else { + cr_log_info("Able to unmap other compartment's memory (runtime not enabled)"); } - printf("res=%d\n", res); - - return 0; -} +} \ No newline at end of file diff --git a/rewriter/tests/permissive_mode/CMakeLists.txt b/rewriter/tests/permissive_mode/CMakeLists.txt index 568005b8f..9b58199ce 100644 --- a/rewriter/tests/permissive_mode/CMakeLists.txt +++ b/rewriter/tests/permissive_mode/CMakeLists.txt @@ -3,6 +3,7 @@ define_test( NEEDS_LD_WRAP PKEY 1 NO_LIBS + CRITERION_TEST ) define_ia2_wrapper( diff --git a/rewriter/tests/permissive_mode/permissive_mode.c b/rewriter/tests/permissive_mode/permissive_mode.c index d18478635..e93417329 100644 --- a/rewriter/tests/permissive_mode/permissive_mode.c +++ b/rewriter/tests/permissive_mode/permissive_mode.c @@ -1,10 +1,12 @@ /* -RUN: %binary_dir/tests/permissive_mode/permissive_mode_main_wrapped +RUN: true */ +// TODO remove the above when lit is removed. As of now a RUN line is required. + #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif -#include +#include #include #include @@ -12,12 +14,12 @@ INIT_RUNTIME(1); #define IA2_COMPARTMENT 1 #include -int main(int argc, char** argv) { +Test(permissive_mode, main) { char* buffer = NULL; - assert(ia2_get_pkru() == 0xFFFFFFF0); + cr_assert(ia2_get_pkru() == 0xFFFFFFF0); /* allocate an extra pkey */ - assert(pkey_alloc(0, PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE) == 2); + cr_assert(pkey_alloc(0, PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE) == 2); buffer = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); @@ -27,7 +29,5 @@ int main(int argc, char** argv) { pkey_mprotect(buffer, 4096, PROT_READ | PROT_WRITE, 2); buffer[0] = 'b'; - assert(ia2_get_pkru() == 0xFFFFFFF0); - - return 0; + cr_assert(ia2_get_pkru() == 0xFFFFFFF0); } diff --git a/rewriter/tests/protected_threads/CMakeLists.txt b/rewriter/tests/protected_threads/CMakeLists.txt index 7077fc54e..3ef430c09 100644 --- a/rewriter/tests/protected_threads/CMakeLists.txt +++ b/rewriter/tests/protected_threads/CMakeLists.txt @@ -9,6 +9,7 @@ define_test( SRCS main.c PKEY 1 NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/protected_threads/main.c b/rewriter/tests/protected_threads/main.c index f6404c70e..6582ebb22 100644 --- a/rewriter/tests/protected_threads/main.c +++ b/rewriter/tests/protected_threads/main.c @@ -1,6 +1,5 @@ /* RUN: sh -c 'if [ ! -s "protected_threads_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' -RUN: %binary_dir/tests/protected_threads/protected_threads_main_wrapped */ #include "library.h" #include @@ -9,6 +8,7 @@ RUN: %binary_dir/tests/protected_threads/protected_threads_main_wrapped #include #include #define IA2_DEFINE_TEST_HANDLER +#include #include #include @@ -18,12 +18,11 @@ INIT_RUNTIME(2); void *nop(void *unused) { return NULL; } -int main() { +Test(protected_threads, main) { pthread_t t; #if IA2_ENABLE int ret = pthread_create(&t, NULL, nop, NULL); + cr_assert(!ret); #endif pthread_join(t, NULL); - - return 0; } diff --git a/rewriter/tests/read_config/CMakeLists.txt b/rewriter/tests/read_config/CMakeLists.txt index 49015d76f..ac20de04b 100644 --- a/rewriter/tests/read_config/CMakeLists.txt +++ b/rewriter/tests/read_config/CMakeLists.txt @@ -8,6 +8,7 @@ define_test( SRCS main.c builtin.c PKEY 1 NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/read_config/builtin.c b/rewriter/tests/read_config/builtin.c index 79590e4c8..bf0f96483 100644 --- a/rewriter/tests/read_config/builtin.c +++ b/rewriter/tests/read_config/builtin.c @@ -1,7 +1,7 @@ /* RUN: cat read_config_call_gates_2.ld | FileCheck --check-prefix=LINKARGS %s */ -#include +#include #include #include #include @@ -47,11 +47,11 @@ struct cfg_opt *get_builtin_opt(char *name) { return &opts[i]; } } - printf("Option %s not found!", name); + cr_log_info("Option %s not found!", name); exit(-1); } // LINKARGS: --wrap=print_array void print_array(uint8_t ar[3]) { - printf("[%x, %x, %x]\n", ar[0], ar[1], ar[2]); + cr_log_info("[%x, %x, %x]", ar[0], ar[1], ar[2]); } diff --git a/rewriter/tests/read_config/main.c b/rewriter/tests/read_config/main.c index f38b85352..030361c5f 100644 --- a/rewriter/tests/read_config/main.c +++ b/rewriter/tests/read_config/main.c @@ -1,6 +1,5 @@ /* RUN: cat read_config_call_gates_2.ld | FileCheck --check-prefix=LINKARGS %s -RUN: %binary_dir/tests/read_config/read_config_main_wrapped | sed -r -e 's/at 0x[0-9a-f]+ //g' | diff %S/Output/read_config.out - RUN: readelf -lW %binary_dir/tests/read_config/read_config_main_wrapped | FileCheck --check-prefix=SEGMENTS %s RUN: cat main.c | FileCheck --match-full-lines --check-prefix=REWRITER %s */ @@ -9,9 +8,10 @@ RUN: cat main.c | FileCheck --match-full-lines --check-prefix=REWRITER %s // SEGMENTS-COUNT-1: LOAD{{.*}}R E // SEGMENTS-NOT: LOAD{{.*}}R E #include "plugin.h" +#include +#include #include #include -#include #include // TODO: Add the `#include output_header.h` to shared headers since they may // need wrapped function pointer definitions. For now just hack around this by @@ -69,11 +69,12 @@ void parse_u32(char *opt, void *out) { *res = strtol(opt, NULL, 10); } -int main(int arcg, char **argv) { +Test(read_config, main) { // Pretend that the heap is intentionally shared for now char *cfg = (char *)shared_malloc(strlen(config_file)); if (!cfg) { - return -1; + cr_log_error("Could not perform shared malloc"); + exit(EXIT_FAILURE); } strcpy(cfg, config_file); @@ -132,26 +133,26 @@ int main(int arcg, char **argv) { } for (size_t i = 0; i < PLUGIN_ENTRIES + BUILTIN_ENTRIES; i++) { - printf("%s ", entries[i].name); + cr_log_info("%s ", entries[i].name); switch (entries[i].ty) { case str: { - printf("%s\n", entries[i].value.str); + cr_log_info("%s", entries[i].value.str); break; } case boolean: { if (entries[i].value.boolean) { - printf("true\n"); + cr_log_info("true"); } else { - printf("false\n"); + cr_log_info("false"); } break; } case u32: { - printf("%d\n", entries[i].value.integer); + cr_log_info("%d", entries[i].value.integer); break; } case other: { - printf("at %p ", entries[i].value.other); + cr_log_info("at %p ", entries[i].value.other); if (i < PLUGIN_ENTRIES) { // Passing this pointer to the plugin is fine since we allocate via // shared_malloc. diff --git a/rewriter/tests/read_config/plugin.c b/rewriter/tests/read_config/plugin.c index ff806e7bb..a7ab90053 100644 --- a/rewriter/tests/read_config/plugin.c +++ b/rewriter/tests/read_config/plugin.c @@ -8,7 +8,7 @@ RUN: readelf -lW %binary_dir/tests/read_config/libread_config_lib_wrapped.so | F #include "plugin.h" #include "core.h" #include -#include +#include #include #include @@ -79,12 +79,12 @@ struct cfg_opt *get_opt(char *name) { return &opts[i]; } } - printf("Option %s not found!", name); + cr_log_info("Option %s not found!", name); exit(-1); } // LINKARGS: --wrap=print_tuple void print_tuple(struct tuple *tup) { // These derefs are fine since the heap is shared. - printf("(%x, %x)\n", tup->first, tup->second); + cr_log_info("(%x, %x)", tup->first, tup->second); } diff --git a/rewriter/tests/recursion/CMakeLists.txt b/rewriter/tests/recursion/CMakeLists.txt index 3d166b471..3d79ea7ee 100644 --- a/rewriter/tests/recursion/CMakeLists.txt +++ b/rewriter/tests/recursion/CMakeLists.txt @@ -12,6 +12,7 @@ define_test( PKEY 1 NEEDS_LD_WRAP INCLUDE_DIR include/dso + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/recursion/dso.c b/rewriter/tests/recursion/dso.c index 62aace3c0..2241c05df 100644 --- a/rewriter/tests/recursion/dso.c +++ b/rewriter/tests/recursion/dso.c @@ -2,6 +2,7 @@ RUN: cat recursion_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ #include "recursion_main.h" +#include #include #include @@ -10,8 +11,8 @@ RUN: cat recursion_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s // LINKARGS: --wrap=recurse_dso void recurse_dso(int count) { - printf("recursion_dso: %d\n", count); - if (count > 0) { - recurse_main(count - 1); - } + cr_log_info("recursion_dso: %d\n", count); + if (count > 0) { + recurse_main(count - 1); + } } diff --git a/rewriter/tests/recursion/main.c b/rewriter/tests/recursion/main.c index 3f243be73..555c057dc 100644 --- a/rewriter/tests/recursion/main.c +++ b/rewriter/tests/recursion/main.c @@ -1,11 +1,12 @@ /* RUN: cat recursion_call_gates_2.ld | FileCheck --check-prefix=LINKARGS %s -RUN: %binary_dir/tests/recursion/recursion_main_wrapped | diff %S/Output/recursion.out - */ +#include "recursion_dso.h" +#include +#include #include #include -#include "recursion_dso.h" #define IA2_DEFINE_TEST_HANDLER #include "test_fault_handler.h" @@ -15,15 +16,12 @@ INIT_RUNTIME(2); // LINKARGS: --wrap=recurse_main void recurse_main(int count) { - printf("recursion_main: %d\n", count); - if (count > 0) { - recurse_dso(count - 1); - } + cr_log_info("recursion_main: %d\n", count); + if (count > 0) { + recurse_dso(count - 1); + } } -int main() { - recurse_main(5); - - // We fault in a destructor while exiting, TODO: #112 - expect_fault = true; +Test(recursion, main) { + recurse_main(5); } diff --git a/rewriter/tests/rewrite_fn_ptr_eq/CMakeLists.txt b/rewriter/tests/rewrite_fn_ptr_eq/CMakeLists.txt index 3cf926439..d99591788 100644 --- a/rewriter/tests/rewrite_fn_ptr_eq/CMakeLists.txt +++ b/rewriter/tests/rewrite_fn_ptr_eq/CMakeLists.txt @@ -5,6 +5,7 @@ define_shared_lib( define_test( SRCS main.c NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/rewrite_fn_ptr_eq/lib.c b/rewriter/tests/rewrite_fn_ptr_eq/lib.c index 7fa4c3758..2229abbe5 100644 --- a/rewriter/tests/rewrite_fn_ptr_eq/lib.c +++ b/rewriter/tests/rewrite_fn_ptr_eq/lib.c @@ -1,6 +1,8 @@ /* RUN: cat rewrite_fn_ptr_eq_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ +#include +#include #include #include #include @@ -8,8 +10,8 @@ RUN: cat rewrite_fn_ptr_eq_call_gates_1.ld | FileCheck --check-prefix=LINKARGS % // LINKARGS: --wrap=call_fn int call_fn(bin_op fn, int x, int y) { - assert(fn != NULL); + cr_assert(fn != NULL); int res = fn(x, y); - printf("%d\n", res); + cr_log_info("%d\n", res); return res; } diff --git a/rewriter/tests/rewrite_fn_ptr_eq/main.c b/rewriter/tests/rewrite_fn_ptr_eq/main.c index 91064302c..f8fe55e22 100644 --- a/rewriter/tests/rewrite_fn_ptr_eq/main.c +++ b/rewriter/tests/rewrite_fn_ptr_eq/main.c @@ -1,6 +1,7 @@ /* RUN: cat main.c | FileCheck --match-full-lines --check-prefix=REWRITER %S/main.c */ +#include #include #include #include @@ -22,7 +23,7 @@ struct module { bin_op fn; }; -int main() { +Test(rewrite_fn_ptr_eq, main) { int res; int *y = &res; void *x = NULL; diff --git a/rewriter/tests/rewrite_macros/CMakeLists.txt b/rewriter/tests/rewrite_macros/CMakeLists.txt index 3cf926439..d99591788 100644 --- a/rewriter/tests/rewrite_macros/CMakeLists.txt +++ b/rewriter/tests/rewrite_macros/CMakeLists.txt @@ -5,6 +5,7 @@ define_shared_lib( define_test( SRCS main.c NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/rewrite_macros/main.c b/rewriter/tests/rewrite_macros/main.c index b31333b52..75ca0df85 100644 --- a/rewriter/tests/rewrite_macros/main.c +++ b/rewriter/tests/rewrite_macros/main.c @@ -4,12 +4,13 @@ RUN: cat main.c | FileCheck --match-full-lines --check-prefix=REWRITER %s #include "lib.h" #include #include +#include INIT_RUNTIME(1); #define IA2_COMPARTMENT 1 #include -int main() { +Test(rewrite_macros, main) { init_actions(); // The next two lines use macros that cannot be easily rewritten so the diff --git a/rewriter/tests/ro_sharing/CMakeLists.txt b/rewriter/tests/ro_sharing/CMakeLists.txt index 91a21362f..5f34f402d 100644 --- a/rewriter/tests/ro_sharing/CMakeLists.txt +++ b/rewriter/tests/ro_sharing/CMakeLists.txt @@ -9,6 +9,7 @@ define_test( SRCS main.c PKEY 1 NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/ro_sharing/main.c b/rewriter/tests/ro_sharing/main.c index 07da8775c..64722ad92 100644 --- a/rewriter/tests/ro_sharing/main.c +++ b/rewriter/tests/ro_sharing/main.c @@ -1,9 +1,9 @@ /* RUN: sh -c 'if [ ! -s "ro_sharing_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' -RUN: %binary_dir/tests/ro_sharing/ro_sharing_main_wrapped plugin | diff %S/Output/plugin.out - -RUN: %binary_dir/tests/ro_sharing/ro_sharing_main_wrapped main | diff %S/Output/main.out - */ -#include "plugin.h" +#include +#include +#include #include #include #define IA2_DEFINE_TEST_HANDLER @@ -28,21 +28,13 @@ const uint32_t main_shared_ro = 0x09431233; // Global in .data uint32_t main_secret_rw = 0x88997766; -int main(int argc, char **argv) { - if (argc < 2) { - printf("Run with `plugin` or `main` as the first argument\n"); - return -1; - } - - if (!strcmp(argv[1], "plugin")) { - LOG("%s", get_plugin_str()); - LOG("0x%x", *get_plugin_uint(false)); - CHECK_VIOLATION(LOG("0x%x", *get_plugin_uint(true))); - } else if (!strcmp(argv[1], "main")) { - read_main_string(main_str); - read_main_uint(&main_shared_ro, &main_secret_rw); - } else { - printf("Invalid argument\n"); - return -1; - } +Test(ro_sharing, main) { + read_main_string(main_str); + read_main_uint(&main_shared_ro, &main_secret_rw); } + +Test(ro_sharing, plugin) { + cr_log_info("%s", get_plugin_str()); + cr_log_info("0x%x", *get_plugin_uint(false)); + cr_log_info("0x%x", CHECK_VIOLATION(*get_plugin_uint(true))); +} \ No newline at end of file diff --git a/rewriter/tests/ro_sharing/plugin.c b/rewriter/tests/ro_sharing/plugin.c index eb330d474..f50ab959b 100644 --- a/rewriter/tests/ro_sharing/plugin.c +++ b/rewriter/tests/ro_sharing/plugin.c @@ -2,10 +2,12 @@ RUN: cat ro_sharing_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ #include "test_fault_handler.h" +#include #include #include #include #include +#include #define IA2_COMPARTMENT 2 #include @@ -35,14 +37,15 @@ const uint32_t *get_plugin_uint(bool secret) { // LINKARGS: --wrap=read_main_string void read_main_string(const char *str) { // Check that we can read a string passed from main - LOG("%s", str); + cr_log_info("%s", str); } // LINKARGS: --wrap=read_main_uint void read_main_uint(const uint32_t *shared, const uint32_t *secret) { // Check that we can read a pointer to rodata passed from main - LOG("0x%x", *shared); + cr_log_info("0x%x", *shared); // Check that we can't read a pointer to data passed from main - CHECK_VIOLATION(LOG("0x%x", *secret)); + // TODO can we change this LOG to cr_log_info? + cr_log_info("0x%x", CHECK_VIOLATION(*secret)); } diff --git a/rewriter/tests/shared_data/CMakeLists.txt b/rewriter/tests/shared_data/CMakeLists.txt index 36a00245b..679d93d99 100644 --- a/rewriter/tests/shared_data/CMakeLists.txt +++ b/rewriter/tests/shared_data/CMakeLists.txt @@ -7,6 +7,7 @@ define_shared_lib( define_test( SRCS main.c NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/shared_data/access_shared.c b/rewriter/tests/shared_data/access_shared.c index da3ff3e65..434732b08 100644 --- a/rewriter/tests/shared_data/access_shared.c +++ b/rewriter/tests/shared_data/access_shared.c @@ -3,16 +3,18 @@ RUN: cat shared_data_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ #include #include "access_shared.h" +#include // LINKARGS: --wrap=read_shared -void read_shared(uint8_t *shared) { - printf("read %d from shared variable\n", *shared); +uint8_t read_shared(uint8_t *shared) { + cr_log_info("read %d from shared variable\n", *shared); + return *shared; } // LINKARGS: --wrap=write_shared uint8_t write_shared(uint8_t *shared, uint8_t new_value) { uint8_t old_value = *shared; - printf("writing %d to shared variable\n", new_value); + cr_log_info("writing %d to shared variable\n", new_value); *shared = new_value; return old_value; } diff --git a/rewriter/tests/shared_data/include/access_shared.h b/rewriter/tests/shared_data/include/access_shared.h index addf254d5..a5c32b6e0 100644 --- a/rewriter/tests/shared_data/include/access_shared.h +++ b/rewriter/tests/shared_data/include/access_shared.h @@ -2,7 +2,7 @@ #define ACCESS_SHARED_H #include -void read_shared(uint8_t *shared); +uint8_t read_shared(uint8_t *shared); uint8_t write_shared(uint8_t *shared, uint8_t new_value); diff --git a/rewriter/tests/shared_data/main.c b/rewriter/tests/shared_data/main.c index 33aa6f0b0..726791aff 100644 --- a/rewriter/tests/shared_data/main.c +++ b/rewriter/tests/shared_data/main.c @@ -1,11 +1,11 @@ /* RUN: sh -c 'if [ ! -s "shared_data_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' -RUN: %binary_dir/tests/shared_data/shared_data_main_wrapped | diff %S/Output/shared_data.out - */ #include #include #include #include "access_shared.h" +#include INIT_RUNTIME(1); #define IA2_COMPARTMENT 1 @@ -15,15 +15,16 @@ uint8_t shared_val[4097] IA2_SHARED_DATA = { 0 }; void check_shared_access(uint8_t *shared) { uint8_t original = *shared; - read_shared(shared); - assert(original == *shared); + uint8_t result = read_shared(shared); + cr_assert(original == *shared); + cr_assert(original == result); uint8_t old_val = write_shared(shared, original + 1); - assert(original == old_val); + cr_assert(original == old_val); } -int main() { +Test(shared_data, main) { shared_val[0] = 23; shared_val[4096] = 254; check_shared_access(&shared_val[0]); check_shared_access(&shared_val[4096]); -} +} \ No newline at end of file diff --git a/rewriter/tests/should_segfault/CMakeLists.txt b/rewriter/tests/should_segfault/CMakeLists.txt index 0e3935426..236fb34c7 100644 --- a/rewriter/tests/should_segfault/CMakeLists.txt +++ b/rewriter/tests/should_segfault/CMakeLists.txt @@ -7,6 +7,7 @@ define_shared_lib( define_test( SRCS main.c NEEDS_LD_WRAP + CRITERION_TEST ) # Build the wrapper lib diff --git a/rewriter/tests/should_segfault/main.c b/rewriter/tests/should_segfault/main.c index fbfbdfec6..53f4c2ec4 100644 --- a/rewriter/tests/should_segfault/main.c +++ b/rewriter/tests/should_segfault/main.c @@ -1,8 +1,7 @@ /* RUN: sh -c 'if [ ! -s "should_segfault_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' -RUN: %binary_dir/tests/should_segfault/should_segfault_main_wrapped | diff %S/Output/should_segfault.out - -RUN: not %binary_dir/tests/should_segfault/should_segfault_main_wrapped early_fault | diff %S/Output/early_segfault.out - */ +#include #include #include #include @@ -19,13 +18,16 @@ uint32_t secret = 0xdeadbeef; // This tests that mpk violations call the signal handler in // test_fault_handler.h and print the appropriate message if the -// segfault occurred in one of the CHECK_VIOLATION expressions. Passing in any -// argument raises a segfault early to test that a violation outside a -// CHECK_VIOLATION prints a different message. -int main(int argc, char **argv) { - if (argc > 1) { - do_early_fault(); - } - printf("TRUSTED: the secret is %x\n", secret); +// segfault occurred in one of the CHECK_VIOLATION expressions. +// We also check raising a segfault early to test that a violation outside a +// CHECK_VIOLATION results in a exit code of -1 (255). + +Test(should_segfault, main) { + cr_assert(secret); print_secret(); } + +Test(should_segfault, early_fault, .exit_code = 255) { + do_early_fault(); + print_secret(); +} \ No newline at end of file diff --git a/rewriter/tests/should_segfault/print_secret.c b/rewriter/tests/should_segfault/print_secret.c index 559c08c7e..2d506ccd1 100644 --- a/rewriter/tests/should_segfault/print_secret.c +++ b/rewriter/tests/should_segfault/print_secret.c @@ -1,6 +1,7 @@ /* RUN: cat should_segfault_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ +#include #include #include #include @@ -21,5 +22,5 @@ void print_secret() { if (early_fault) { raise(SIGSEGV); } - printf("UNTRUSTED: the secret is %x\n", CHECK_VIOLATION(secret)); + cr_assert(CHECK_VIOLATION(secret)); } diff --git a/rewriter/tests/sighandler/CMakeLists.txt b/rewriter/tests/sighandler/CMakeLists.txt index b1f2c4276..a0d07c5b8 100644 --- a/rewriter/tests/sighandler/CMakeLists.txt +++ b/rewriter/tests/sighandler/CMakeLists.txt @@ -9,6 +9,7 @@ define_test( SRCS main.c NEEDS_LD_WRAP PKEY 1 + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/sighandler/include/lib.h b/rewriter/tests/sighandler/include/lib.h index 353155f76..2e3fcf694 100644 --- a/rewriter/tests/sighandler/include/lib.h +++ b/rewriter/tests/sighandler/include/lib.h @@ -1,5 +1,8 @@ #pragma once +#include + extern int lib_secret; void test_handler_from_lib(void); +void install_sighandler_in_lib(bool rewrite); \ No newline at end of file diff --git a/rewriter/tests/sighandler/lib.c b/rewriter/tests/sighandler/lib.c index a70e0ff64..e4b02c68b 100644 --- a/rewriter/tests/sighandler/lib.c +++ b/rewriter/tests/sighandler/lib.c @@ -5,13 +5,53 @@ RUN: cat sighandler_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s #include "lib.h" #include #include +#include +#define IA2_DEFINE_TEST_HANDLER +#include #define IA2_COMPARTMENT 2 #include +extern int main_secret; int lib_secret = 4; +struct handler { + IA2_IGNORE(void (*handler)(int sig)); +}; + +void trap_handler_lib(int sig) { + volatile int test = lib_secret; + volatile int test2 = CHECK_VIOLATION(main_secret); +}; + +IA2_DEFINE_SIGHANDLER(trap_handler_lib, 2); + // LINKARGS: --wrap=test_handler_from_lib void test_handler_from_lib(void) { raise(SIGTRAP); } + +void install_sighandler_lib(struct handler *h) { + static struct sigaction sa; + memset(&sa, 0, sizeof(struct sigaction)); + sigemptyset(&(sa.sa_mask)); + + if (h) { + sa.sa_handler = h->handler; + } else { + sa.sa_handler = IA2_SIGHANDLER(trap_handler_lib); + } + sigaction(SIGTRAP, &sa, NULL); + cr_log_info("Installed SIGTRAP handler in lib"); +} + +void install_sighandler_in_lib(bool rewrite) { + if (rewrite) { + install_sighandler_lib(NULL); + } else { + static struct handler h = { + .handler = IA2_SIGHANDLER(trap_handler_lib), + }; + install_sighandler_lib(&h); + } +} \ No newline at end of file diff --git a/rewriter/tests/sighandler/main.c b/rewriter/tests/sighandler/main.c index 12163433c..8773c4164 100644 --- a/rewriter/tests/sighandler/main.c +++ b/rewriter/tests/sighandler/main.c @@ -1,5 +1,5 @@ /* -RUN: %binary_dir/tests/sighandler/sighandler_main_wrapped | diff %S/Output/main.out - +RUN: true */ #include "lib.h" #include @@ -7,6 +7,7 @@ RUN: %binary_dir/tests/sighandler/sighandler_main_wrapped | diff %S/Output/main. #include #define IA2_DEFINE_TEST_HANDLER #include +#include INIT_RUNTIME(2); #define IA2_COMPARTMENT 1 @@ -20,16 +21,8 @@ struct handler { int main_secret = 3; void trap_handler(int sig) { - const char *main_msg = "trap_handler: main_secret is "; - const char *lib_msg = "trap_handler: lib_secret is "; - write(1, main_msg, strlen(main_msg)); - char num = '0' + main_secret; - write(1, &num, 1); - write(1, "\n", 1); - write(1, lib_msg, strlen(lib_msg)); - num = '0' + CHECK_VIOLATION(lib_secret); - write(1, &num, 1); - write(1, "\n", 1); + volatile int test = main_secret; + volatile int test2 = CHECK_VIOLATION(lib_secret); }; IA2_DEFINE_SIGHANDLER(trap_handler, 1); @@ -47,19 +40,25 @@ void install_sighandler(struct handler *h) { sigaction(SIGTRAP, &sa, NULL); } -void test_handler(void) { +Test(sighandler, main_rewriter) { + install_sighandler(NULL); raise(SIGTRAP); - test_handler_from_lib(); } -int main() { - setbuf(stdout, NULL); - install_sighandler(NULL); - test_handler(); - +Test(sighandler, main_ignore) { static struct handler h = { .handler = IA2_SIGHANDLER(trap_handler), }; install_sighandler(&h); - test_handler(); + raise(SIGTRAP); } + +Test(sighandler, lib_rewriter) { + install_sighandler_in_lib(true); + test_handler_from_lib(); +} + +Test(sighandler, lib_ignore) { + install_sighandler_in_lib(false); + test_handler_from_lib(); +} \ No newline at end of file diff --git a/rewriter/tests/simple1/CMakeLists.txt b/rewriter/tests/simple1/CMakeLists.txt index d152ca581..74b00be02 100644 --- a/rewriter/tests/simple1/CMakeLists.txt +++ b/rewriter/tests/simple1/CMakeLists.txt @@ -8,6 +8,7 @@ define_test( SRCS main.c NEEDS_LD_WRAP PKEY 1 + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/simple1/main.c b/rewriter/tests/simple1/main.c index 594df00ba..5bc21c5a4 100644 --- a/rewriter/tests/simple1/main.c +++ b/rewriter/tests/simple1/main.c @@ -2,6 +2,9 @@ RUN: cat main.c | FileCheck --match-full-lines --check-prefix=REWRITER %s RUN: cat simple1_call_gates_0.ld | FileCheck --check-prefix=LINKARGS %s */ +#include +#include +#include #include #include #include @@ -45,7 +48,7 @@ static void main_write(int x) { putchar(x); } static int main_map(int x) { return x ? (x ^ last_xor) : x; } -int main() { +Test(simple1, main) { // These will be called from untrusted code but may access trusted compartment // 0 struct SimpleCallbacks scb = { @@ -57,8 +60,7 @@ int main() { struct Simple *s = simple_new(scb); if (s == NULL) { - printf("Error allocating Simple\n"); - return -1; + cr_fatal("Error allocating Simple\n"); } srand(time(NULL)); @@ -83,6 +85,4 @@ int main() { // REWRITER: IA2_CALL(exit_hook_fn, 0)(); exit_hook_fn(); } - - return 0; } diff --git a/rewriter/tests/simple1/simple1.c b/rewriter/tests/simple1/simple1.c index f0b4fba59..155f57282 100644 --- a/rewriter/tests/simple1/simple1.c +++ b/rewriter/tests/simple1/simple1.c @@ -2,6 +2,7 @@ Source rewriter pass is a noop for PKEY=0. RUN: cat simple1_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ +#include #include #include #include @@ -11,7 +12,7 @@ RUN: cat simple1_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s static bool did_set_exit_hook = false; -static void simple_exit_hook(void) { printf("libsimple exiting...\n"); } +static void simple_exit_hook(void) { cr_log_info("libsimple exiting...\n"); } struct Simple { struct SimpleCallbacks scb; @@ -46,7 +47,7 @@ struct Simple *simple_new(struct SimpleCallbacks scb) { if (!did_set_exit_hook) { set_exit_hook(simple_exit_hook); did_set_exit_hook = true; - printf("New exit hook fn: %p\n", get_exit_hook()); + cr_log_info("New exit hook fn: %p\n", get_exit_hook()); } struct Simple *s = malloc(sizeof(struct Simple)); diff --git a/rewriter/tests/structs/CMakeLists.txt b/rewriter/tests/structs/CMakeLists.txt index f4d070867..d9e5f4239 100644 --- a/rewriter/tests/structs/CMakeLists.txt +++ b/rewriter/tests/structs/CMakeLists.txt @@ -8,6 +8,7 @@ define_shared_lib( define_test( SRCS main.c NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/structs/include/structs.h b/rewriter/tests/structs/include/structs.h index 84ebe5f69..9459c568a 100644 --- a/rewriter/tests/structs/include/structs.h +++ b/rewriter/tests/structs/include/structs.h @@ -154,8 +154,8 @@ struct s5 get_s5(void); // LINKARGS: --wrap=get_s5_int struct s5 get_s5_int(int); -// LINKARGS: --wrap=print_s5 -void print_s5(struct s5 ); +// LINKARGS: --wrap=check_s5 +void check_s5(struct s5 ); // LINKARGS: --wrap=cksum_s5_f float cksum_s5_f(struct s5); diff --git a/rewriter/tests/structs/main.c b/rewriter/tests/structs/main.c index a33c60f42..ba85a5a7c 100644 --- a/rewriter/tests/structs/main.c +++ b/rewriter/tests/structs/main.c @@ -1,12 +1,11 @@ /* RUN: sh -c 'if [ ! -s "structs_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' -RUN: %binary_dir/tests/structs/structs_main_wrapped | diff %S/Output/structs.out - */ -#include +#include +#include #include "structs.h" #include #include -#include /* This program tests that a trusted binary can pass and return structs of various shapes @@ -17,27 +16,23 @@ INIT_RUNTIME(1); #define IA2_COMPARTMENT 1 #include -#define check_close_float(name, val) { printf("%s(s) = %.4f (expected %.4f)\n", #name, name(s), val); } -#define check_field_float(name, val) { printf("s.%s = %.4f (expected %.4f)\n", #name, s.name, val); } +#define EPSILON 0.0001f -#define check_eq_int(name, val) { printf("%s(s) = %d (expected %d)\n", #name, name(s), val); } -#define check_field_int(name, val) { printf("s.%s = %d (expected %d)\n", #name, (int)s.name, val); } +#define check_close_float(name, val) { cr_assert_lt(fabs(name(s) - (val)), EPSILON); } +#define check_field_float(name, val) { cr_assert_lt(fabs(s.name - (val)), EPSILON); } -#define check_eq_size(name, val) { printf("%s(s) = %zd (expected %zd)\n", #name, name(s), (size_t)(val)); } -#define check_field_size(name, val) { printf("s.%s = %zd (expected %zd)\n", #name, (size_t)s.name, (size_t)(val)); } +#define check_eq_int(name, val) { cr_assert(name(s) == val); } +#define check_field_int(name, val) { cr_assert(s.name == val); } -#define check_field_ptr(name, val) { printf("s.%s = %p (expected %p)\n", #name, s.name, (void*)(val)); } +#define check_eq_size(name, val) { cr_assert(name(s) == (size_t)val); } +#define check_field_size(name, val) { cr_assert(s.name == (size_t)val); } -#define check_eq_i128(name, upper, lower) { __int128 out = name(s); \ - printf("%s(s) = %016lx%016lx (expected %016lx%016lx)\n", #name, \ - (int64_t)(out >> 64), (int64_t)(out & 0xffffffffffffffff), \ - (int64_t)(upper), (uint64_t)(lower)); } -#define check_field_i128(name, upper, lower) { __int128 out = s.name; \ - printf("s.%s = %016lx%016lx (expected %016lx%016lx)\n", #name, \ - (int64_t)(out >> 64), (int64_t)(out & 0xffffffffffffffff), \ - (int64_t)(upper), (uint64_t)(lower)); } +#define check_field_ptr(name, val) { cr_assert(s.name == (void*)val); } -int main() { +#define check_eq_i128(name, val) { cr_assert(name(s) == (__int128)val); } +#define check_field_i128(name, val) { cr_assert(s.name == (__int128)val); } + +Test(structs, main) { /* For each struct, test passing it to functions, returning it from functions (see structs.c), and calls with various combinations of argument/return types. */ { @@ -56,10 +51,10 @@ int main() { .f1 = 999.99, }; check_close_float(extract_s2, s.f1); - assert(extract_s2(s) == s.f1); - assert(fabs(extract_s2(s) - 999.99) < 0.0001); + cr_assert(extract_s2(s) == s.f1); + cr_assert(fabs(extract_s2(s) - 999.99) < EPSILON); s = get_s2(); - assert(fabs(s.f1 - 3.14) < 0.0001); + cr_assert(fabs(s.f1 - 3.14) < EPSILON); } { @@ -68,7 +63,7 @@ int main() { .c1 = 5, .u1 = 5071, }; - assert(cksum_s3(s) == 400 + 5 + 5071); + cr_assert(cksum_s3(s) == 400 + 5 + 5071); s = get_s3(); check_field_int(i1, 50); check_field_int(c1, 65); @@ -94,7 +89,7 @@ int main() { .p2 = (void*)0xba5edba5edba5ed, .f1 = 390.56, }; - print_s5(s); + check_s5(s); check_close_float(cksum_s5_f, 390.56); check_eq_size(cksum_s5_z, 6976 + 0xb17ebee7 + 78 + 45 + 32 + 0xba5edba5edba5ed); s = get_s5(); @@ -177,7 +172,7 @@ int main() { .i2 = 549, .i3 = 1500, }; - check_eq_i128(cksum_s9, 0, 2002 + 549 + 1500); + check_eq_i128(cksum_s9, 2002 + 549 + 1500); s = get_s9(); check_field_int(i1, 96506328); check_field_int(i2, 1846); @@ -191,11 +186,11 @@ int main() { .i3 = 1240, .z1 = 100500, }; - check_eq_i128(cksum_s10, 0, 40504030 + 540 + 1240 + 100500); + check_eq_i128(cksum_s10, 40504030 + 540 + 1240 + 100500); s = get_s10(); - check_field_i128(i1, 0, 96506328); - check_field_i128(i2, 0, 1846); - check_field_i128(i3, 0, 3254); + check_field_i128(i1, 96506328); + check_field_i128(i2, 1846); + check_field_i128(i3, 3254); check_field_size(z1, 6853785); } @@ -264,7 +259,7 @@ int main() { (0xddddcccc & 0xffffffff) + (0x7fffeeee & 0xffffffff)); s = get_s13(); - check_field_i128(x, 0x7fffeeeeddddcccc, 0xbbbbaaaa99998888); + check_field_i128(x, (((__int128)0x7fffeeeeddddcccc << 64) | 0xbbbbaaaa99998888)); } { @@ -313,5 +308,4 @@ int main() { check_field_int(field7, 70000); check_field_int(field8, 80000); } - return 0; } diff --git a/rewriter/tests/structs/structs.c b/rewriter/tests/structs/structs.c index 1c132a157..3f33df73c 100644 --- a/rewriter/tests/structs/structs.c +++ b/rewriter/tests/structs/structs.c @@ -2,7 +2,19 @@ RUN: cat structs_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ #include "structs.h" -#include +#include +#include + +// LINKARGS: --wrap=check_s5 +void check_s5(struct s5 s) { + cr_assert_eq(s.i1, 6976); + cr_assert_eq(s.p1, (void*)0xb17ebee7); + cr_assert_eq(s.ac1[0], 78); + cr_assert_eq(s.ac1[1], 45); + cr_assert_eq(s.ac1[2], 32); + cr_assert_eq(s.p2, (void*)0xba5edba5edba5ed); + cr_assert_lt(fabs(s.f1 - 390.5600f), 0.0001f); +} // LINKARGS: --wrap=cksum_s1 int cksum_s1(struct s1 s) { @@ -314,10 +326,3 @@ struct s6 mix_s6(struct s6 s1, struct s6 s2) { s1.z1 += s2.z1 / 2; return s1; } - -// LINKARGS: --wrap=print_s5 -void print_s5(struct s5 s) { - printf("s5 { %d %p [%d,%d,%d] %p %.4f }\n", - s.i1, s.p1, s.ac1[0], s.ac1[1], s.ac1[2], s.p2, s.f1); -} - diff --git a/rewriter/tests/threads/CMakeLists.txt b/rewriter/tests/threads/CMakeLists.txt index 7bb4bc193..ce152c2eb 100644 --- a/rewriter/tests/threads/CMakeLists.txt +++ b/rewriter/tests/threads/CMakeLists.txt @@ -8,6 +8,7 @@ define_test( SRCS main.c PKEY 1 NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/threads/library.c b/rewriter/tests/threads/library.c index 475041e6f..f74ad0b0b 100644 --- a/rewriter/tests/threads/library.c +++ b/rewriter/tests/threads/library.c @@ -1,6 +1,8 @@ /* RUN: cat threads_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ +#include +#include #include "library.h" #include #include @@ -13,12 +15,16 @@ int library_access_int_ptr(int *ptr) { return *ptr; } // LINKARGS: --wrap=library_call_fn void library_call_fn(Fn what) { - printf("in lib, about to call fnptr; lib data: %d\n", data_in_lib); + cr_log_info("in lib, about to call fnptr; lib data: %d\n", data_in_lib); + cr_assert_eq(data_in_lib, 900); what(); } // LINKARGS: --wrap=library_foo -void library_foo() { printf("data in library: %d\n", data_in_lib); } +void library_foo() { + cr_log_info("data in library: %d\n", data_in_lib); + cr_assert_eq(data_in_lib, 900); +} // LINKARGS: --wrap=library_memset void library_memset(void *ptr, uint8_t byte, size_t n) { @@ -29,7 +35,11 @@ void library_memset(void *ptr, uint8_t byte, size_t n) { } // LINKARGS: --wrap=library_showpkru -void library_showpkru(void) { printf("library pkru %08x\n", ia2_get_pkru()); } +void library_showpkru() { + uint32_t actual_pkru = ia2_get_pkru(); + cr_log_info("library pkru %08x", actual_pkru); + cr_assert_eq(0xfffffffc, actual_pkru); +} static void *library_showpkru_thread_main(void *unused) { library_showpkru(); diff --git a/rewriter/tests/threads/main.c b/rewriter/tests/threads/main.c index c9a79f00e..cfbc8c6c2 100644 --- a/rewriter/tests/threads/main.c +++ b/rewriter/tests/threads/main.c @@ -1,7 +1,8 @@ /* RUN: sh -c 'if [ ! -s "threads_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' -RUN: %binary_dir/tests/threads/threads_main_wrapped | FileCheck --dump-input=always -v %S/Output/threads.out */ +#include +#include #include "library.h" #include #include @@ -18,20 +19,24 @@ INIT_RUNTIME(1); int data_in_main = 30; -void defined_in_main(void) { printf("main data is %d\n", data_in_main); } +void defined_in_main(void) { + cr_log_info("main data is %d\n", data_in_main); + cr_assert_eq(data_in_main, 30); +} Fn fnptr_from_main = defined_in_main; void *thread_fn(void *ptr); void *thread_fn(void *ptr) { - printf("tid %d ptr=%p\n", gettid(), ptr); + cr_log_info("tid %d ptr=%p\n", gettid(), ptr); - printf("main-module thread pkru=%08x\n", ia2_get_pkru()); + cr_log_info("main-module thread pkru=%08x\n", ia2_get_pkru()); + cr_assert_eq(ia2_get_pkru(), 0xfffffff0); library_showpkru(); - printf("ptr is %p, formatting int: %08zx\n", ptr, 4300 + (size_t)ptr); + cr_log_info("ptr is %p, formatting int: %08zx\n", ptr, 4300 + (size_t)ptr); return NULL; } @@ -50,16 +55,17 @@ __thread int thread_local_var = 50; void *access_ptr_thread_fn(void *ptr) { int *x = (int *)ptr; - printf("c1t3 accessing c1t1 thread-local: %d\n", *x); - printf("c2t3 accessing c1t1 thread-local: %d\n", + cr_log_info("c1t3 accessing c1t1 thread-local: %d\n", *x); + cr_log_info("c2t3 accessing c1t1 thread-local: %d\n", CHECK_VIOLATION(library_access_int_ptr(x))); return NULL; } -int main() { - printf("main-module main pkru=%08x\n", ia2_get_pkru()); +Test(threads, main) { + cr_log_info("main-module main pkru=%08x\n", ia2_get_pkru()); + cr_assert_eq(ia2_get_pkru(), 0xfffffff0); library_showpkru(); - printf("main-module main pkru=%08x\n", ia2_get_pkru()); + cr_log_info("main-module main pkru=%08x\n", ia2_get_pkru()); pthread_t lib_thread = library_spawn_thread(); @@ -78,6 +84,4 @@ int main() { &fault_thread, NULL, access_ptr_thread_fn, (void *)&thread_local_var); #endif pthread_join(fault_thread, NULL); - - return 0; } diff --git a/rewriter/tests/tls_protected/CMakeLists.txt b/rewriter/tests/tls_protected/CMakeLists.txt index 32cc63619..352eb3f6d 100644 --- a/rewriter/tests/tls_protected/CMakeLists.txt +++ b/rewriter/tests/tls_protected/CMakeLists.txt @@ -11,6 +11,7 @@ define_test( SRCS main.c PKEY 1 NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/tls_protected/library.c b/rewriter/tests/tls_protected/library.c index 8bfa61b02..96bab6b86 100644 --- a/rewriter/tests/tls_protected/library.c +++ b/rewriter/tests/tls_protected/library.c @@ -7,9 +7,10 @@ RUN: readelf -lW %binary_dir/tests/tls_protected/libtls_protected_lib_wrapped.so // SEGMENTS-NOT: LOAD{{.*}}R E #include "library.h" #include "test_fault_handler.h" +#include +#include #include #include -#include #include #define IA2_COMPARTMENT 2 @@ -18,11 +19,12 @@ RUN: readelf -lW %binary_dir/tests/tls_protected/libtls_protected_lib_wrapped.so thread_local uint32_t lib_secret = 0x1eaf1e55; void lib_print_main_secret() { - printf("library: going to access main secret\n"); - printf("library: accessing main secret at %p\n", &main_secret); - printf("library: main secret is %x\n", CHECK_VIOLATION(main_secret)); + cr_log_info("library: going to access main secret\n"); + cr_log_info("library: accessing main secret at %p\n", &main_secret); + cr_log_info("library: main secret is %x\n", CHECK_VIOLATION(main_secret)); + cr_assert(false); // should not reach here } void lib_print_lib_secret() { - printf("library: lib secret is %x\n", lib_secret); + cr_log_info("library: lib secret is %x\n", lib_secret); } diff --git a/rewriter/tests/tls_protected/main.c b/rewriter/tests/tls_protected/main.c index 9ee7bacae..30129b5f6 100644 --- a/rewriter/tests/tls_protected/main.c +++ b/rewriter/tests/tls_protected/main.c @@ -1,13 +1,13 @@ /* -RUN: %binary_dir/tests/tls_protected/tls_protected_main_wrapped | FileCheck --dump-input=always -v %S/Output/tls_protected_main.out -RUN: %binary_dir/tests/tls_protected/tls_protected_main_wrapped print_lib_secret | FileCheck --dump-input=always -v %S/Output/tls_protected_lib.out +RUN: true */ +#include +#include #include #include #include #include -#include #include #define IA2_DEFINE_TEST_HANDLER #include "test_fault_handler.h" @@ -26,37 +26,41 @@ volatile void *addr; // segfault occurred in one of the CHECK_VIOLATION expressions. Passing in any // argument raises a segfault early to test that a violation outside a // CHECK_VIOLATION prints a different message. -int main(int argc, char **argv) { - +void run_test(bool access_lib_secret) { errno = 5; - printf("errno=%d, pkru=%08x\n", errno, ia2_get_pkru()); + cr_log_info("errno=%d, pkru=%08x\n", errno, ia2_get_pkru()); lib_print_lib_secret(); // Access to thread-local from the same compartment should work. - printf("main: main secret is %x\n", main_secret); - printf("errno=%d, pkru=%08x\n", errno, ia2_get_pkru()); + cr_log_info("main: main secret is %x\n", main_secret); + cr_log_info("errno=%d, pkru=%08x\n", errno, ia2_get_pkru()); lib_print_lib_secret(); - printf("errno=%d, pkru=%08x\n", errno, ia2_get_pkru()); - // If we have an argument, test the "main accessing lib" direction; - // otherwise test the "lib accessing main" direction. Both should - // exit with an MPK violation. - bool access_lib_secret = argc > 1; + cr_log_info("errno=%d, pkru=%08x\n", errno, ia2_get_pkru()); errno = 5; - printf("pkru=%08x\n", ia2_get_pkru()); - printf("errno=%d\n", errno); + cr_log_info("pkru=%08x\n", ia2_get_pkru()); + cr_log_info("errno=%d\n", errno); // Perform forbidden access. if (access_lib_secret) { - printf("main: going to access lib secret\n"); + cr_log_info("main: going to access lib secret\n"); addr = &lib_secret; if (addr != 0) { - printf("main: accessing lib secret at %p\n", addr); + cr_log_info("main: accessing lib secret at %p\n", addr); } - printf("main: lib secret is %x\n", CHECK_VIOLATION(lib_secret)); + cr_log_info("main: lib secret is %x\n", CHECK_VIOLATION(lib_secret)); + cr_assert(false); // Should not reach here } else { lib_print_main_secret(); } } + +Test(tls_protected, no_access_lib_secret) { + run_test(false); +} + +Test(tls_protected, access_lib_secret) { + run_test(true); +} \ No newline at end of file diff --git a/rewriter/tests/trusted_direct/CMakeLists.txt b/rewriter/tests/trusted_direct/CMakeLists.txt index 1c0f09b9d..d9d363871 100644 --- a/rewriter/tests/trusted_direct/CMakeLists.txt +++ b/rewriter/tests/trusted_direct/CMakeLists.txt @@ -10,6 +10,7 @@ define_test( SRCS main.c INCLUDE_DIR include/plugin NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/trusted_direct/main.c b/rewriter/tests/trusted_direct/main.c index eca0d1128..45823ecfb 100644 --- a/rewriter/tests/trusted_direct/main.c +++ b/rewriter/tests/trusted_direct/main.c @@ -1,10 +1,9 @@ /* RUN: cat trusted_direct_call_gates_0.ld | FileCheck --check-prefix=LINKARGS %s -RUN: %binary_dir/tests/trusted_direct/trusted_direct_main_wrapped | diff %S/Output/trusted_direct.out - -RUN: %binary_dir/tests/trusted_direct/trusted_direct_main_wrapped clean_exit | diff %S/Output/trusted_direct.clean_exit.out - */ +#include +#include #include -#include #include #include @@ -27,12 +26,16 @@ bool clean_exit IA2_SHARED_DATA = false; //LINKARGS: --wrap=print_message void print_message(void) { - printf("%s: the secret 0x%" PRIx32 " is defined in the main binary\n", __func__, secret); + cr_log_info("%s: the secret 0x%" PRIx32 " is defined in the main binary\n", __func__, secret); + cr_assert(secret == 0x09431233); } -int main(int argc, char **argv) { - if (argc > 1) { - clean_exit = true; - } +Test(trusted_direct, no_clean_exit) { + clean_exit = false; + start_plugin(); +} + +Test(trusted_direct, clean_exit) { + clean_exit = true; start_plugin(); } diff --git a/rewriter/tests/trusted_direct/plugin.c b/rewriter/tests/trusted_direct/plugin.c index ef8fda3cb..ce0b7b239 100644 --- a/rewriter/tests/trusted_direct/plugin.c +++ b/rewriter/tests/trusted_direct/plugin.c @@ -1,15 +1,17 @@ /* RUN: cat trusted_direct_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ -#include +#include +#include #include "exported_fn.h" #include "test_fault_handler.h" // LINKARGS: --wrap=start_plugin void start_plugin(void) { - printf("%s: this is defined in the plugin\n", __func__); + cr_log_info("%s: this is defined in the plugin\n", __func__); print_message(); if (!clean_exit) { - printf("%s: the secret is %d\n", __func__, CHECK_VIOLATION(secret)); + cr_log_info("%s: the secret is %d\n", __func__, CHECK_VIOLATION(secret)); + cr_fatal("Should have segfaulted on cross-boundary access"); } } diff --git a/rewriter/tests/trusted_indirect/CMakeLists.txt b/rewriter/tests/trusted_indirect/CMakeLists.txt index b05f5660f..691a065ac 100644 --- a/rewriter/tests/trusted_indirect/CMakeLists.txt +++ b/rewriter/tests/trusted_indirect/CMakeLists.txt @@ -3,6 +3,7 @@ define_shared_lib(SRCS rand_op.c) define_test( SRCS main.c NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/trusted_indirect/main.c b/rewriter/tests/trusted_indirect/main.c index f1fa73720..953711f25 100644 --- a/rewriter/tests/trusted_indirect/main.c +++ b/rewriter/tests/trusted_indirect/main.c @@ -1,10 +1,9 @@ /* RUN: cat main.c | FileCheck --match-full-lines --check-prefix=REWRITER %s RUN: sh -c 'if [ ! -s "trusted_indirect_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' -RUN: %binary_dir/tests/trusted_indirect/trusted_indirect_main_wrapped | diff %S/Output/trusted_indirect.out - -RUN: %binary_dir/tests/trusted_indirect/trusted_indirect_main_wrapped clean_exit | diff %S/Output/trusted_indirect.clean_exit.out - */ -#include +#include +#include #include "rand_op.h" #include #define IA2_DEFINE_TEST_HANDLER @@ -33,27 +32,25 @@ static uint32_t divide(uint32_t x, uint32_t y) { void call_fn_ptr() { function_t f = get_function(); - printf("Got the function %s from the library\n", f.name); + cr_log_info("Got the function %s from the library\n", f.name); uint32_t x = 987234; uint32_t y = 142151; // This calls `f.op` with and without parentheses to ensure the rewriter handles both - // REWRITER: uint32_t res = IA2_CALL(f.op, 0)(x, y); - uint32_t res = f.op(x, y); - printf("%s(%d, %d) = %d\n", f.name, x, y, res); + // REWRITER: uint32_t res1 = IA2_CALL(f.op, 0)(x, y); + uint32_t res1 = f.op(x, y); // REWRITER: f.op = IA2_FN(multiply); f.op = multiply; - // REWRITER: printf("mul(%d, %d) = %d\n", x, y, IA2_CALL((f.op), 0)(x, y)); - printf("mul(%d, %d) = %d\n", x, y, (f.op)(x, y)); + // REWRITER: uint32_t res2 = IA2_CALL((f.op), 0)(x, y); + uint32_t res2 = (f.op)(x, y); + cr_assert_eq(res2, 2897346862); // REWRITER: f.op = IA2_FN(divide); f.op = divide; - // REWRITER: printf("div(%d, %d) = %d\n", x, y, IA2_CALL(f.op, 0)(x, y)); - printf("div(%d, %d) = %d\n", x, y, f.op(x, y)); + // REWRITER: uint32_t res3 = IA2_CALL(f.op, 0)(x, y); + uint32_t res3 = f.op(x, y); + cr_assert_eq(res3, 6); } -int main(int argc, char **argv) { - if (argc > 1) { - clean_exit = true; - } +void do_test() { // Test calling a function pointer with one of the shared library's functions call_fn_ptr(); @@ -69,3 +66,13 @@ int main(int argc, char **argv) { // REWRITER: IA2_CALL((f.op), 0)(0, 0); (f.op)(0, 0); } + +Test(trusted_indirect, no_clean_exit) { + clean_exit = false; + do_test(); +} + +Test(trusted_indirect, clean_exit) { + clean_exit = true; + do_test(); +} diff --git a/rewriter/tests/trusted_indirect/rand_op.c b/rewriter/tests/trusted_indirect/rand_op.c index 38d988821..7f5b5d7d1 100644 --- a/rewriter/tests/trusted_indirect/rand_op.c +++ b/rewriter/tests/trusted_indirect/rand_op.c @@ -2,7 +2,9 @@ RUN: cat trusted_indirect_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s */ -#include +#include +#include +#include #include #include "rand_op.h" #include "test_fault_handler.h" @@ -22,7 +24,8 @@ uint32_t add(uint32_t x, uint32_t y) { static uint32_t steal_secret(uint32_t x, uint32_t y) { if (!clean_exit) { if (secret_address) { - printf("the secret is %x\n", CHECK_VIOLATION(*secret_address)); + cr_log_info("the secret is %x\n", CHECK_VIOLATION(*secret_address)); + cr_fatal("Should have segfaulted here"); } } return 0; diff --git a/rewriter/tests/two_keys_minimal/CMakeLists.txt b/rewriter/tests/two_keys_minimal/CMakeLists.txt index 21612d33c..1f12bbacb 100644 --- a/rewriter/tests/two_keys_minimal/CMakeLists.txt +++ b/rewriter/tests/two_keys_minimal/CMakeLists.txt @@ -12,6 +12,7 @@ define_test( INCLUDE_DIR include/plugin NEEDS_LD_WRAP PKEY 1 + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/two_keys_minimal/main.c b/rewriter/tests/two_keys_minimal/main.c index 76701158e..514526819 100644 --- a/rewriter/tests/two_keys_minimal/main.c +++ b/rewriter/tests/two_keys_minimal/main.c @@ -1,9 +1,6 @@ /* RUN: sh -c 'if [ ! -s "should_segfault_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' RUN: cat two_keys_minimal_call_gates_2.ld | FileCheck --check-prefix=LINKARGS %s -RUN: %binary_dir/tests/two_keys_minimal/two_keys_minimal_main_wrapped plugin | diff %S/Output/plugin.out - -RUN: %binary_dir/tests/two_keys_minimal/two_keys_minimal_main_wrapped main | diff %S/Output/main.out - -RUN: %binary_dir/tests/two_keys_minimal/two_keys_minimal_main_wrapped clean_exit | diff %S/Output/clean_exit.out - RUN: readelf -lW %binary_dir/tests/two_keys_minimal/two_keys_minimal_main_wrapped | FileCheck --check-prefix=SEGMENTS %s */ @@ -11,6 +8,8 @@ RUN: readelf -lW %binary_dir/tests/two_keys_minimal/two_keys_minimal_main_wrappe // SEGMENTS-COUNT-1: LOAD{{.*}}R E // SEGMENTS-NOT: LOAD{{.*}}R E +#include +#include #include #include #include @@ -35,32 +34,26 @@ bool clean_exit IA2_SHARED_DATA = false; // LINKARGS: --wrap=print_message void print_message(void) { - LOG("this is defined in the main binary"); + cr_log_info("this is defined in the main binary"); if (debug_mode) { - LOG("the main secret is at %p", &secret); + cr_log_info("the main secret is at %p", &secret); } - LOG("the main secret is %x", secret); + cr_assert(secret == 0x09431233); if (steal_plugin_secret) { - LOG("the plugin secret is %x\n", CHECK_VIOLATION(plugin_secret)); + cr_assert(CHECK_VIOLATION(plugin_secret) == 0x78341244); } } -int main(int argc, char **argv) { - if (argc < 2) { - printf("Run with `plugin`, `main` or `clean_exit` as the first argument\n"); - return -1; - } - if (!strcmp(argv[1], "plugin")) { - LOG("checking if the plugin secret is safe"); - steal_plugin_secret = true; - } else if (!strcmp(argv[1], "main")) { - LOG("checking if the main secret is safe"); - } else { - LOG("checking if the program can exit cleanly"); - clean_exit = true; - } - if (argc == 3 && !strcmp(argv[2], "debug")) { - debug_mode = true; - } +Test(two_keys, main) { + start_plugin(); +} + +Test(two_keys, plugin) { + steal_plugin_secret = true; + start_plugin(); +} + +Test(two_keys, clean_exit) { + clean_exit = true; start_plugin(); } diff --git a/rewriter/tests/two_keys_minimal/plugin.c b/rewriter/tests/two_keys_minimal/plugin.c index 9cab7defa..94735fc5a 100644 --- a/rewriter/tests/two_keys_minimal/plugin.c +++ b/rewriter/tests/two_keys_minimal/plugin.c @@ -7,6 +7,8 @@ RUN: readelf -lW %binary_dir/tests/two_keys_minimal/libtwo_keys_minimal_lib_wrap // SEGMENTS-COUNT-1: LOAD{{.*}}R E // SEGMENTS-NOT: LOAD{{.*}}R E +#include +#include #include #include #include "exported_fn.h" @@ -21,13 +23,13 @@ extern bool clean_exit; // LINKARGS: --wrap=start_plugin void start_plugin(void) { - LOG("this is defined in the plugin"); + cr_log_info("this is defined in the plugin"); if (debug_mode) { - LOG("the plugin secret is at %p", &plugin_secret); + cr_log_info("the plugin secret is at %p", &plugin_secret); } - LOG("the plugin secret is %x", plugin_secret); + cr_assert(plugin_secret == 0x78341244); print_message(); if (!clean_exit) { - LOG("the main secret is %x", CHECK_VIOLATION(secret)); + cr_assert(CHECK_VIOLATION(secret) == 0x09431233); } } diff --git a/rewriter/tests/two_shared_ranges/CMakeLists.txt b/rewriter/tests/two_shared_ranges/CMakeLists.txt index dc47e09c0..69a395633 100644 --- a/rewriter/tests/two_shared_ranges/CMakeLists.txt +++ b/rewriter/tests/two_shared_ranges/CMakeLists.txt @@ -12,6 +12,7 @@ define_test( PKEY 1 NEEDS_LD_WRAP INCLUDE_DIR include/plugin + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/two_shared_ranges/include/main/exported_fn.h b/rewriter/tests/two_shared_ranges/include/main/exported_fn.h index f083c0ae7..dc884bbe0 100644 --- a/rewriter/tests/two_shared_ranges/include/main/exported_fn.h +++ b/rewriter/tests/two_shared_ranges/include/main/exported_fn.h @@ -10,5 +10,3 @@ void print_message(void); extern uint32_t secret; extern uint32_t shared; - -extern bool debug_mode; diff --git a/rewriter/tests/two_shared_ranges/main.c b/rewriter/tests/two_shared_ranges/main.c index f25b082e0..1d551c8a1 100644 --- a/rewriter/tests/two_shared_ranges/main.c +++ b/rewriter/tests/two_shared_ranges/main.c @@ -1,8 +1,5 @@ /* RUN: cat two_shared_ranges_call_gates_2.ld | FileCheck --check-prefix=LINKARGS %s -RUN: %binary_dir/tests/two_shared_ranges/two_shared_ranges_main_wrapped plugin | diff %S/Output/plugin.out - -RUN: %binary_dir/tests/two_shared_ranges/two_shared_ranges_main_wrapped main | diff %S/Output/main.out - -RUN: %binary_dir/tests/two_shared_ranges/two_shared_ranges_main_wrapped clean_exit | diff %S/Output/clean_exit.out - RUN: readelf -lW %binary_dir/tests/two_shared_ranges/two_shared_ranges_main_wrapped | FileCheck --check-prefix=SEGMENTS %s */ @@ -10,7 +7,8 @@ RUN: readelf -lW %binary_dir/tests/two_shared_ranges/two_shared_ranges_main_wrap // SEGMENTS-COUNT-1: LOAD{{.*}}R E // SEGMENTS-NOT: LOAD{{.*}}R E -#include +#include +#include #include #include #include "plugin.h" @@ -26,43 +24,31 @@ uint32_t secret = 0x09431233; uint32_t shared IA2_SHARED_DATA = 0xb75784ee; static bool steal_plugin_secret = false; -// Running in debug mode prints the addresses of the secrets defined in each -// compartment. This is off by default to simplify the diff of stdout against -// the expected output. -bool debug_mode IA2_SHARED_DATA = false; bool clean_exit IA2_SHARED_DATA = false; // LINKARGS: --wrap=print_message void print_message(void) { - LOG("this is defined in the main binary"); - if (debug_mode) { - LOG("the main secret is at %p", &secret); - LOG("the plugin shared data is at %p", &plugin_shared); - } - LOG("the main secret is %x", secret); - LOG("the plugin shared data is %x", plugin_shared); + cr_log_info("this is defined in the main binary"); + cr_log_info("the main secret is at %p", &secret); + cr_log_info("the plugin shared data is at %p", &plugin_shared); + cr_log_info("the main secret is %x", secret); + cr_log_info("the plugin shared data is %x", plugin_shared); if (steal_plugin_secret) { - LOG("the plugin secret is %x\n", CHECK_VIOLATION(plugin_secret)); + cr_log_info("the plugin secret is %x\n", CHECK_VIOLATION(plugin_secret)); } } -int main(int argc, char **argv) { - if (argc < 2) { - printf("Run with `plugin`, `main` or `clean_exit` as the first argument\n"); - return -1; - } - if (!strcmp(argv[1], "plugin")) { - LOG("checking if the plugin secret is safe"); - steal_plugin_secret = true; - } else if (!strcmp(argv[1], "main")) { - LOG("checking if the main secret is safe"); - } else { - LOG("checking if the program can exit cleanly"); - clean_exit = true; - } - if (argc == 3 && !strcmp(argv[2], "debug")) { - debug_mode = true; - } +Test(two_shared_ranges, main) { start_plugin(); } + +Test(two_shared_ranges, plugin) { + steal_plugin_secret = true; + start_plugin(); +} + +Test(two_shared_ranges, clean_exit) { + clean_exit = true; + start_plugin(); +} \ No newline at end of file diff --git a/rewriter/tests/two_shared_ranges/plugin.c b/rewriter/tests/two_shared_ranges/plugin.c index 737347a64..8f61aea98 100644 --- a/rewriter/tests/two_shared_ranges/plugin.c +++ b/rewriter/tests/two_shared_ranges/plugin.c @@ -7,7 +7,7 @@ RUN: readelf -lW %binary_dir/tests/two_shared_ranges/libtwo_shared_ranges_lib_wr // SEGMENTS-COUNT-1: LOAD{{.*}}R E // SEGMENTS-NOT: LOAD{{.*}}R E -#include +#include #include #include "exported_fn.h" #include "test_fault_handler.h" @@ -22,15 +22,13 @@ extern bool clean_exit; // LINKARGS: --wrap=start_plugin void start_plugin(void) { - LOG("this is defined in the plugin"); - if (debug_mode) { - LOG("the plugin secret is at %p", &plugin_secret); - LOG("the main shared data is at %p", &shared); - } - LOG("the plugin secret is %x", plugin_secret); - LOG("the main shared data is %x", shared); + cr_log_info("this is defined in the plugin"); + cr_log_info("the plugin secret is at %p", &plugin_secret); + cr_log_info("the main shared data is at %p", &shared); + cr_log_info("the plugin secret is %x", plugin_secret); + cr_log_info("the main shared data is %x", shared); print_message(); if (!clean_exit) { - LOG("the main secret is %x", CHECK_VIOLATION(secret)); + cr_log_info("the main secret is %x", CHECK_VIOLATION(secret)); } } diff --git a/rewriter/tests/untrusted_indirect/CMakeLists.txt b/rewriter/tests/untrusted_indirect/CMakeLists.txt index 04424fb7d..34e37580f 100644 --- a/rewriter/tests/untrusted_indirect/CMakeLists.txt +++ b/rewriter/tests/untrusted_indirect/CMakeLists.txt @@ -3,6 +3,7 @@ define_shared_lib(SRCS foo.c) define_test( SRCS main.c NEEDS_LD_WRAP + CRITERION_TEST ) define_ia2_wrapper() diff --git a/rewriter/tests/untrusted_indirect/foo.c b/rewriter/tests/untrusted_indirect/foo.c index 94a994e7a..2441cb56a 100644 --- a/rewriter/tests/untrusted_indirect/foo.c +++ b/rewriter/tests/untrusted_indirect/foo.c @@ -1,11 +1,10 @@ /* RUN: cat untrusted_indirect_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s -RUN: %binary_dir/tests/untrusted_indirect/untrusted_indirect_main_wrapped | diff %S/Output/untrusted_indirect.out - -RUN: %binary_dir/tests/untrusted_indirect/untrusted_indirect_main_wrapped clean_exit | diff %S/Output/untrusted_indirect.clean_exit.out - */ +#include +#include #include #include "foo.h" -#include "stdio.h" #include "test_fault_handler.h" extern bool clean_exit; @@ -40,7 +39,7 @@ void unregister_callback() { if (!clean_exit) { // Check for an mpk violation when the library tries to read the main binary's memory uint64_t stolen_secret = CHECK_VIOLATION(*(uint64_t *)last_result); - printf("UNTRUSTED: the secret is 0x%lx\n", stolen_secret); + cr_fatal("Did not segfault on boundary violation"); } } } diff --git a/rewriter/tests/untrusted_indirect/main.c b/rewriter/tests/untrusted_indirect/main.c index ab9305452..950b03e59 100644 --- a/rewriter/tests/untrusted_indirect/main.c +++ b/rewriter/tests/untrusted_indirect/main.c @@ -1,7 +1,8 @@ /* RUN: sh -c 'if [ ! -s "untrusted_indirect_call_gates_0.ld" ]; then echo "No link args as expected"; exit 0; fi; echo "Unexpected link args"; exit 1;' */ -#include +#include +#include #include #include "foo.h" #include @@ -56,21 +57,28 @@ uint64_t leak_secret_address(uint64_t x, uint64_t y) { return (uint64_t)&secret; } -int main(int argc, char **argv) { - if (argc > 1) { - clean_exit = true; - } - printf("TRUSTED: the secret is 0x%lx\n", secret); - printf("0x%lx\n", apply_callback(1, 2)); +void do_test() { + cr_log_info("TRUSTED: the secret is 0x%lx\n", secret); + cr_log_info("0x%lx\n", apply_callback(1, 2)); // REWRITER: register_callback(IA2_FN(pick_rhs)); register_callback(pick_rhs); - printf("0x%lx\n", apply_callback(3, 4)); + cr_log_info("0x%lx\n", apply_callback(3, 4)); // REWRITER: register_callback(IA2_FN(leak_secret_address)); register_callback(leak_secret_address); - printf("TRUSTED: oops we leaked the address of the secret\n"); + cr_log_info("TRUSTED: oops we leaked the address of the secret\n"); apply_callback(5, 6); unregister_callback(); } + +Test(untrusted_indirect, no_clean_exit) { + clean_exit = false; + do_test(); +} + +Test(untrusted_indirect, clean_exit) { + clean_exit = true; + do_test(); +} \ No newline at end of file