From 47b8e520b6275ffdb5936b31aa3665dea7d4ab5a Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Fri, 14 Jul 2023 12:50:03 +0200 Subject: test: fix test-error-check The error-check tests recompile and pass. --- tests/unit/Makefile | 4 +- tests/unit/test_errors.c | 135 +++++++++++++++++++++-------------------------- tests/unit/testutil.h | 15 +++--- tests/unit/util.c | 52 ++++++++++-------- 4 files changed, 97 insertions(+), 109 deletions(-) (limited to 'tests') diff --git a/tests/unit/Makefile b/tests/unit/Makefile index c72eb48..4096cdb 100644 --- a/tests/unit/Makefile +++ b/tests/unit/Makefile @@ -13,7 +13,7 @@ HEADERS_FILTER_BUILD := $(COOKER_DIR)/filter.h $(DBG_DIR)/disasm.h $(COMMON_DIR) $(COMMON_DIR)/util.h SRCS_FILTER := $(COOKER_DIR)/filter.c $(COMMON_DIR)/common.c util.c \ - $(DBG_DIR)/disasm.c + $(DBG_DIR)/disasm.c $(COMMON_DIR)/util.c HEADERS_FILTER := $(COOKER_DIR)/filter.h $(COMMON_DIR)/common.h $(COMMON_DIR)/util.h \ $(DBG_DIR)/disasm.h testutil.h @@ -38,7 +38,7 @@ AUDIT_ARCH := $(shell echo $(AUDIT_ARCH) | sed 's/I[456]86/I386/') AUDIT_ARCH := $(shell echo $(AUDIT_ARCH) | sed 's/PPC64/PPC/') AUDIT_ARCH := $(shell echo $(AUDIT_ARCH) | sed 's/PPCLE/PPC64LE/') -CFLAGS += -Wall -Wextra -pedantic +CFLAGS += -Wall -Wextra -pedantic -std=c99 CFLAGS += -I$(MAIN_DIR) -I$(DBG_DIR) -I$(COMMON_DIR) -I$(COOKER_DIR) CFLAGS += -lcheck CFLAGS += -DSEITAN_AUDIT_ARCH=AUDIT_ARCH_$(AUDIT_ARCH) diff --git a/tests/unit/test_errors.c b/tests/unit/test_errors.c index 0f971cd..3d4064c 100644 --- a/tests/unit/test_errors.c +++ b/tests/unit/test_errors.c @@ -2,7 +2,7 @@ * Copyright 2023 Red Hat GmbH * Author: Alice Frosi */ - +#define _GNU_SOURCE #include #include #include @@ -39,33 +39,46 @@ struct gluten_offset test_max_size_data[] = { START_TEST(test_bound_check) { struct op ops[] = { - { OP_RETURN, OP_EMPTY }, - { OP_END, OP_EMPTY }, + { .type = OP_RETURN, + { .ret = { { test_max_size_data[_i].type, + test_max_size_data[_i].offset } } } }, + { .type = OP_END, { { { 0 } } } }, }; - ops[0].op.ret.val.offset = test_max_size_data[_i].offset; - ops[0].op.ret.val.type = test_max_size_data[_i].type; - write_instr(gluten, ops); - eval(&gluten, &req, notifyfd); + ck_assert_int_eq(eval(&gluten, &req, notifyfd), -1); } START_TEST(test_write_op_return) { - long nr = __NR_getppid; + struct gluten_offset offset = { OFFSET_RO_DATA, 0}; + struct gluten_offset ret_off = { OFFSET_DATA, DATA_SIZE }; struct op ops[] = { - { OP_CALL, - { .call = { .nr = { OFFSET_DATA, 0 }, - .has_ret = true, - .ret = { OFFSET_DATA, DATA_SIZE - 1 } } } }, + { OP_CALL, { .call = { offset } } }, }; - ck_write_gluten(gluten, ops[0].op.call.nr, nr); + char err_msg[200]; + struct syscall_desc_test { + uint32_t nr : 9; + uint32_t arg_count : 3; + uint32_t has_ret : 1; + uint32_t arg_deref : 6; + struct gluten_offset context; /* struct context_desc [] */ + struct gluten_offset args[1]; + } syscall = { + __NR_getppid, 0, 1, 0, { OFFSET_NULL, 0 }, { ret_off }, + }; + + ck_stderr(); + sprintf(err_msg, "failed writing return value at %d", DATA_SIZE); + ck_write_gluten(gluten, syscall, offset); write_instr(gluten, ops); ck_assert_int_eq(eval(&gluten, &req, notifyfd), -1); + ck_error_msg(err_msg); } START_TEST(test_write_op_load) { char a[30]; + char err_msg[200]; struct op ops[] = { { OP_LOAD, { .load = { { OFFSET_SECCOMP_DATA, 1 }, @@ -73,8 +86,10 @@ START_TEST(test_write_op_load) sizeof(a) } } }, }; + ck_stderr(); write_instr(gluten, ops); ck_assert_int_eq(eval(&gluten, &req, notifyfd), -1); + ck_error_msg("offset limits are invalid"); } struct gluten_offset test_max_size_read_data[] = { @@ -85,40 +100,50 @@ struct gluten_offset test_max_size_read_data[] = { START_TEST(test_read_op_return) { + struct gluten_offset offset = { OFFSET_RO_DATA, 0 }; + struct return_desc desc = { { test_max_size_read_data[_i].offset, + test_max_size_read_data[_i].type }, + { OFFSET_NULL, 0 }, + false }; struct op ops[] = { - { OP_RETURN, OP_EMPTY }, - { OP_END, OP_EMPTY }, + { OP_RETURN, { .ret = { offset } } }, }; - ops[0].op.ret.val.offset = test_max_size_read_data[_i].offset - 1; - ops[0].op.ret.val.type = test_max_size_read_data[_i].type; + ck_stderr(); + ck_write_gluten(gluten, desc, offset); write_instr(gluten, ops); ck_assert_int_eq(eval(&gluten, &req, notifyfd), -1); + ck_error_msg("offset limits are invalid"); } -static struct op_cmp test_cmp_data[] = { - { .x = { OFFSET_DATA, DATA_SIZE } }, - { .y = { OFFSET_DATA, DATA_SIZE } }, - { .x = { OFFSET_DATA, DATA_SIZE - 1 }, .size = 10 }, - { .y = { OFFSET_DATA, DATA_SIZE - 1 }, .size = 10 }, - { .jmp = { OFFSET_DATA, DATA_SIZE } }, +static struct cmp_desc test_cmp_data[] = { + { .cmp = CMP_EQ, .x = { OFFSET_DATA, DATA_SIZE } }, + { .cmp = CMP_EQ, .y = { OFFSET_DATA, DATA_SIZE } }, + { .cmp = CMP_EQ, .x = { OFFSET_DATA, DATA_SIZE - 1 }, .size = 10 }, + { .cmp = CMP_EQ, .y = { OFFSET_DATA, DATA_SIZE - 1 }, .size = 10 }, + { .cmp = CMP_EQ, .jmp = { OFFSET_DATA, DATA_SIZE } }, }; START_TEST(test_op_cmp) { - struct op ops[2]; + struct gluten_offset offset = { OFFSET_RO_DATA, 0 }; + struct cmp_desc cmp = { + test_cmp_data[_i].cmp, + test_cmp_data[_i].size, + { test_cmp_data[_i].x.type, test_cmp_data[_i].x.offset }, + { test_cmp_data[_i].y.type, test_cmp_data[_i].y.offset }, + test_cmp_data[_i].jmp + }; + struct op ops[] = { + { OP_CMP, { .cmp = { offset } } }, + }; - ops[0].type = OP_CMP; - ops[0].op.cmp.x.offset = test_cmp_data[_i].x.offset; - ops[0].op.cmp.x.type = test_cmp_data[_i].x.type; - ops[0].op.cmp.y.offset = test_cmp_data[_i].y.offset; - ops[0].op.cmp.y.type = test_cmp_data[_i].y.type; - ops[0].op.cmp.size = test_cmp_data[_i].size; - ops[0].op.cmp.jmp = test_cmp_data[_i].jmp; - ops[1].type = OP_END; + ck_stderr(); + ck_write_gluten(gluten, cmp, offset); write_instr(gluten, ops); ck_assert_int_eq(eval(&gluten, &req, notifyfd), -1); + ck_error_msg("offset limits are invalid"); } struct ttargetnoexisting_data { @@ -126,40 +151,6 @@ struct ttargetnoexisting_data { char err_msg[BUFSIZ]; }; -struct ttargetnoexisting_data test_target_noexisting_data[] = { - { { OP_CONT, OP_EMPTY }, "the response id isn't valid" }, - { { OP_BLOCK, { .block = { -1 } } }, "the response id isn't valid" }, - { { OP_RETURN, { .ret = { { OFFSET_DATA, 0 } } } }, - "the response id isn't valid" }, - { { OP_INJECT, - { .inject = { { OFFSET_DATA, 0 }, { OFFSET_DATA, 0 } } } }, - "the response id isn't valid" }, - { { OP_INJECT_A, - { .inject = { { OFFSET_DATA, 0 }, { OFFSET_DATA, 0 } } } }, - "the response id isn't valid" }, - { { OP_LOAD, - { .load = { { OFFSET_SECCOMP_DATA, 1 }, { OFFSET_DATA, 0 }, 0 } } }, - "error opening mem for" }, - { { OP_RESOLVEDFD, - { .resfd = { { OFFSET_SECCOMP_DATA, 1 }, - { OFFSET_DATA, 0 }, - 0, - 0 } } }, - "error reading /proc" }, -}; - -START_TEST(test_target_noexisting) -{ - struct op ops[2]; - - ops[0] = test_target_noexisting_data[_i].op; - ops[1].type = OP_END; - - write_instr(gluten, ops); - ck_assert_int_eq(eval(&gluten, &req, notifyfd), -1); - ck_error_msg(test_target_noexisting_data[_i].err_msg); -} - Suite *error_suite(void) { Suite *s; @@ -170,8 +161,7 @@ Suite *error_suite(void) bounds = tcase_create("bound checks"); tcase_add_loop_test(bounds, test_bound_check, 0, - sizeof(test_max_size_data) / - sizeof(test_max_size_data[0])); + ARRAY_SIZE(test_max_size_data)); suite_add_tcase(s, bounds); gwrite = tcase_create("write gluten"); @@ -183,8 +173,7 @@ Suite *error_suite(void) gread = tcase_create("read gluten"); tcase_add_checked_fixture(gread, setup_error_check, teardown); tcase_add_loop_test(gread, test_read_op_return, 0, - sizeof(test_max_size_read_data) / - sizeof(test_max_size_read_data[0])); + ARRAY_SIZE(test_max_size_read_data)); suite_add_tcase(s, gread); gcmp = tcase_create("compare gluten"); @@ -193,12 +182,6 @@ Suite *error_suite(void) sizeof(test_cmp_data) / sizeof(test_cmp_data[0])); suite_add_tcase(s, gcmp); - tnotexist = tcase_create("target not existing"); - tcase_add_checked_fixture(tnotexist, setup_stderr, NULL); - tcase_add_loop_test(tnotexist, test_target_noexisting, 0, - ARRAY_SIZE(test_target_noexisting_data)); - suite_add_tcase(s, tnotexist); - return s; } diff --git a/tests/unit/testutil.h b/tests/unit/testutil.h index caccd44..dc1f489 100644 --- a/tests/unit/testutil.h +++ b/tests/unit/testutil.h @@ -25,7 +25,7 @@ static inline void *test_gluten_write_ptr(struct gluten *g, const struct gluten_offset x) { - ck_assert_msg(is_offset_valid(x), "offset out of bounds"); + ck_assert_msg(is_offset_valid(x), "offset %d out of bounds", x.offset); switch (x.type) { case OFFSET_DATA: @@ -45,18 +45,18 @@ static inline void *test_gluten_write_ptr(struct gluten *g, memcpy(test_gluten_write_ptr(&gluten, x), &ops, sizeof(ops)); \ } while (0) -#define ck_write_gluten(gluten, value, ref) \ - do { \ - void *p = test_gluten_write_ptr(&gluten, value); \ - ck_assert_ptr_nonnull(p); \ - memcpy(p, &ref, sizeof(ref)); \ +#define ck_write_gluten(gluten, value, offset) \ + do { \ + void *p = test_gluten_write_ptr(&gluten, offset); \ + ck_assert_ptr_nonnull(p); \ + memcpy(p, &value, sizeof(value)); \ } while (0) #define ck_read_gluten(gluten, value, ref) \ do { \ void *p = test_gluten_write_ptr(&gluten, value); \ ck_assert_ptr_nonnull(p); \ - memcpy(&ref, p, sizeof(ref)); \ + memcpy(&value, p, sizeof(value)); \ } while (0) #define NS_NUM CONTEXT_TYPE_MAX - 3 struct args_target { @@ -102,7 +102,6 @@ void set_args_no_check(struct args_target *at); void check_target_result_nonegative(); void ck_error_msg(char *s); void ck_stderr(); -void ck_stdout(); int install_single_syscall(long nr); int read_filter(struct sock_filter filter[], char *file); #endif /* TESTUTIL_H */ diff --git a/tests/unit/util.c b/tests/unit/util.c index 26f13e0..9409ff2 100644 --- a/tests/unit/util.c +++ b/tests/unit/util.c @@ -35,22 +35,10 @@ struct args_target *at; int pipefd[2]; pid_t pid; char path[PATH_MAX] = "/tmp/test-seitan"; +/* TODO: randomize the outfile name */ +char logfile[PATH_MAX] = "/tmp/seitan-test.log"; struct gluten gluten; -char stderr_buff[BUFSIZ]; -char stdout_buff[BUFSIZ]; - -#define logfn(name) \ -void name(const char *format, ...) { \ - va_list args; \ - \ - va_start(args, format); \ - (void)vfprintf(stderr, format, args); \ - va_end(args); \ - if (format[strlen(format)] != '\n') \ - fprintf(stderr, "\n"); \ -} - -logfn(debug) +FILE *fperr; int install_single_syscall(long nr) { @@ -291,27 +279,45 @@ void setup() (req.data).nr); } +static void teardown_stderr() +{ + fclose(fperr); + unlink(logfile); +} + void teardown() { if (at != NULL) munmap(at, sizeof(struct args_target)); + if (fperr != NULL) + teardown_stderr(); unlink(path); } void ck_stderr() { - setbuf(stderr, stderr_buff); -} - -void ck_stdout() -{ - setbuf(stdout, stdout_buff); + fprintf(stderr, "Redirect stderr to %s\n", logfile); + fperr = freopen (logfile, "a+", stderr); } void ck_error_msg(char *s) { - ck_assert_msg(strstr(stderr_buff, s) != NULL, "err=\"%s\" doesn't contain \"%s\" ", - stderr_buff, s); + char line[256]; + FILE *file; + + if (fperr == NULL) + ck_abort_msg("need to call ck_stderr"); + + fflush(stderr); + file = fopen(logfile, "r"); + while (fgets(line, sizeof(line), file)) { + if(strstr(line, s) != NULL) { + return; + } + } + fclose(file); + + ck_abort_msg("doesn't find \"%s\"", s); } int read_filter(struct sock_filter filter[], char *file) -- cgit v1.2.3