Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve testing framework #286

Merged
merged 28 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9efbb91
Convert two_keys_minimal to use criterion
rinon Sep 21, 2023
d4449db
Remove function_allowlist test
rinon Sep 22, 2023
91eba1f
Convert should_segfault to Criterion
sim-immunant Sep 25, 2023
809316a
Convert ro_sharing test to Criterion
sim-immunant Sep 26, 2023
85ea82d
Convert global_fn_ptr to Criterion
sim-immunant Sep 26, 2023
49fbe87
Convert minimal
sim-immunant Sep 26, 2023
5418287
Convert mmap_loop
sim-immunant Sep 26, 2023
1e38c48
Convert permissive_mode
sim-immunant Sep 26, 2023
1737964
Convert protected_threads
sim-immunant Sep 27, 2023
474f3e8
Convert recursion
sim-immunant Sep 27, 2023
510cd2b
Convert rewrite_fn_ptr_eq
sim-immunant Sep 27, 2023
d4663ff
Convert rewrite_macros to Criterion
sim-immunant Sep 27, 2023
d167336
PR feedback
sim-immunant Sep 27, 2023
f648db4
Convert shared_data
sim-immunant Sep 27, 2023
7f82f6e
Fix sighandler test
sim-immunant Oct 2, 2023
8f5282b
Convert simple1
sim-immunant Oct 2, 2023
c36b904
Structs test
sim-immunant Oct 4, 2023
96a352d
Convert threads test to Criterion
sim-immunant Oct 5, 2023
90d1251
Convert tls_protected to Criterion
sim-immunant Oct 5, 2023
6f137c5
trusted_direct
sim-immunant Oct 5, 2023
2a2f37d
trusted_indirect
sim-immunant Oct 6, 2023
7cc669e
two_shared_ranged
sim-immunant Oct 6, 2023
b56daec
untrusted_indirect
sim-immunant Oct 6, 2023
0c3f151
read_config
sim-immunant Oct 6, 2023
1fc0e8a
header_includes
sim-immunant Oct 6, 2023
247eb2e
heap_two_keys
sim-immunant Oct 7, 2023
40f076b
macro_attr
sim-immunant Oct 7, 2023
3fe7a35
Replace some error and quit with cr_fatal
sim-immunant Oct 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion cmake/define-test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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()
Expand Down
7 changes: 4 additions & 3 deletions rewriter/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
include(CTest)

enable_testing()

include("../../cmake/define-ia2-wrapper.cmake")
Expand All @@ -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)
Expand Down
13 changes: 0 additions & 13 deletions rewriter/tests/function_allowlist/CMakeLists.txt

This file was deleted.

This file was deleted.

7 changes: 0 additions & 7 deletions rewriter/tests/function_allowlist/include/library.h

This file was deleted.

1 change: 0 additions & 1 deletion rewriter/tests/function_allowlist/include/library.h.fns

This file was deleted.

8 changes: 0 additions & 8 deletions rewriter/tests/function_allowlist/library.c

This file was deleted.

20 changes: 0 additions & 20 deletions rewriter/tests/function_allowlist/main.c

This file was deleted.

1 change: 1 addition & 0 deletions rewriter/tests/global_fn_ptr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ define_shared_lib(
define_test(
SRCS main.c
NEEDS_LD_WRAP
CRITERION_TEST
)

# Build the wrapper lib
Expand Down
3 changes: 1 addition & 2 deletions rewriter/tests/global_fn_ptr/include/operations.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
/*
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
#include <stdlib.h>
#include <stdint.h>

// 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);
Expand Down
7 changes: 4 additions & 3 deletions rewriter/tests/global_fn_ptr/main.c
Original file line number Diff line number Diff line change
@@ -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 <ia2.h>
#include <criterion/criterion.h>

uint32_t add(uint32_t x, uint32_t y) { return x + y; }
uint16_t sub(uint16_t x, uint16_t y) { return x - y; }
Expand Down Expand Up @@ -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);
}
19 changes: 9 additions & 10 deletions rewriter/tests/global_fn_ptr/operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@
RUN: cat global_fn_ptr_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s
*/
#include "operations.h"
#include <criterion/criterion.h>
#include <stdio.h>

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think we can remove the comment on the printf and the TODO We previously treated the .rodata sections (where string literals are placed) as secret, but we have since moved on to only treating writable sections that way.

uint32_t x = 18923;
uint32_t y = 24389;
uint32_t res = operations[i].function(x, y);
return res;
}
1 change: 1 addition & 0 deletions rewriter/tests/header_includes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ define_shared_lib(
define_test(
SRCS main.c
NEEDS_LD_WRAP
CRITERION_TEST
)

# Build the wrapper lib
Expand Down
6 changes: 3 additions & 3 deletions rewriter/tests/header_includes/liboption.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/*
RUN: cat header_includes_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s
*/
#include <stdio.h>
#include <criterion/logging.h>
#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,
Expand All @@ -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,
Expand Down
9 changes: 5 additions & 4 deletions rewriter/tests/header_includes/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <stdio.h>
#include <criterion/criterion.h>
#include <criterion/logging.h>
#include <ia2.h>

INIT_RUNTIME(1);
#define IA2_COMPARTMENT 1
#include <ia2_compartment_init.inc>

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);
}
1 change: 1 addition & 0 deletions rewriter/tests/heap_two_keys/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ define_test(
PKEY 1
NEEDS_LD_WRAP
INCLUDE_DIR include/plugin
CRITERION_TEST
)

define_ia2_wrapper()
64 changes: 13 additions & 51 deletions rewriter/tests/heap_two_keys/main.c
Original file line number Diff line number Diff line change
@@ -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 <stdio.h>
#include <criterion/criterion.h>
#include <criterion/logging.h>
#include <criterion/new/assert.h>
#include <unistd.h>
#include <assert.h>
#include <ia2.h>
Expand All @@ -20,81 +18,45 @@ INIT_RUNTIME(2);
#include <ia2_compartment_init.inc>

// 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)
1 change: 1 addition & 0 deletions rewriter/tests/macro_attr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ define_shared_lib(
define_test(
SRCS main.c
NEEDS_LD_WRAP
CRITERION_TEST
)

# Build the wrapper lib
Expand Down
Loading