From 12d77297b590beb6688e32c142ce13d91e30c51a Mon Sep 17 00:00:00 2001 From: Alice Frosi Date: Tue, 24 Jan 2023 17:05:32 +0100 Subject: test: add unit test for act call Tests: - getppid syscall - read syscall without context - opena and read syscalls with a mount namespace Signed-off-by: Alice Frosi --- tests/unit/Makefile | 7 +- tests/unit/test_action_call.c | 225 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 tests/unit/test_action_call.c (limited to 'tests') diff --git a/tests/unit/Makefile b/tests/unit/Makefile index 3270052..5e7116b 100644 --- a/tests/unit/Makefile +++ b/tests/unit/Makefile @@ -1,5 +1,10 @@ CFLAGS += -lcheck -test: test-filter.c +test: test-filter test-actions +test-filter: test-filter.c $(CC) $(CFLAGS) -o test-filter ../../filter.c ../../disasm.c test-filter.c ./test-filter + +test-actions: test_action_call.c ../../actions.c ../../actions.h + $(CC) $(CFLAGS) -o test-action-call ../../actions.c test_action_call.c + ./test-action-call diff --git a/tests/unit/test_action_call.c b/tests/unit/test_action_call.c new file mode 100644 index 0000000..3ea1874 --- /dev/null +++ b/tests/unit/test_action_call.c @@ -0,0 +1,225 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../../gluten.h" +#include "../../actions.h" + +struct args_write_file { + char *file; + char *t; + ssize_t size; +}; + + +static void write_file(char *file, char *t, ssize_t size) +{ + ssize_t n; + int fd; + + fd = open(file, O_CREAT | O_RDWR, S_IWUSR |S_IRUSR); + ck_assert_int_ge(fd, -1); + n = write(fd,t, size); + close(fd); +} + +static int write_file_get_fd(char *file, char *t, ssize_t size) +{ + int fd; + + write_file(file, t, size); + fd = open(file, O_RDONLY, S_IWUSR); + unlink(file); + return fd; +}; + +static int write_file_clone(void *a) +{ + struct args_write_file *args = (struct args_write_file *)a; + write_file(args->file, args->t, args->size); + pause(); + return 0; +} + +static pid_t create_func_ns(int (*fn)(void *), void *arg, struct ns_spec ns[]) +{ + char stack[STACK_SIZE]; + pid_t child; + int flags = SIGCHLD; + unsigned int i; + + for (i=0; i < sizeof(sizeof(enum ns_type)); i++) + { + if (ns[i].type == NS_NONE) + continue; + switch(i){ + case NS_CGROUP: + flags |= CLONE_NEWCGROUP; + break; + case NS_IPC: + flags |= CLONE_NEWIPC; + break; + case NS_NET: + flags |= CLONE_NEWNET; + break; + case NS_MOUNT: + flags |= CLONE_NEWNS; + break; + case NS_PID: + flags |= CLONE_NEWPID; + break; + case NS_USER: + flags |= CLONE_NEWUSER; + break; + case NS_UTS: + flags |= CLONE_NEWUTS; + break; + case NS_TIME: + fprintf(stderr, "option NS_TIME not suppoted by clone\n"); + break; + default: + fprintf(stderr, "unrecognized option %d\n", i); + } + } + child = clone(fn, stack + sizeof(stack), flags, arg); + if (child == -1) { + perror("clone"); + exit(EXIT_FAILURE); + } + return child; +} + +START_TEST(test_with_open_read_ns) +{ + char test_file[] = "/tmp/test.txt"; + char t[PATH_MAX] = "Hello Test"; + struct args_write_file args = { + test_file, t, sizeof(t)}; + struct ns_spec ns[NS_NUM]; + struct act_call call; + int flags = O_RDWR; + struct arg_clone c; + char buf[PATH_MAX]; + unsigned i; + long count; + ssize_t n; + pid_t pid; + int ret; + + c.args = &call; + count = sizeof(buf); + for(i = 0; i < sizeof(enum ns_type); i++) + call.context.ns[i].type = NS_NONE; + call.context.ns[NS_MOUNT].type = NS_SPEC_PID; + pid = create_func_ns(write_file_clone, (void *)&args, call.context.ns); + call.context.ns[NS_MOUNT].pid = pid; + call.nr = SYS_open; + call.args[0] = (void *)&test_file; + call.args[1] = (void *)(long)flags; + ret = do_call(&c); + ck_assert_int_eq(ret, 0); + ck_assert_msg(c.ret >= 0, "expect ret %ld should be nonegative", c.ret); + + call.nr = SYS_read; + call.args[0] = (void *)(long) c.ret; + call.args[1] = (void *)&buf; + call.args[2] = (void *)count; + ret = do_call(&c); + kill(pid, SIGCONT); + + ck_assert_int_eq(ret, 0); + ck_assert_msg(c.ret == count, + "expect ret %ld to be %ld",c.ret, count); + ck_assert_str_eq(t, buf); +} +END_TEST + +START_TEST(test_with_read) +{ + char test_file[] = "/tmp/test.txt"; + char t[PATH_MAX] = "Hello Test"; + struct act_call call; + struct arg_clone c; + char buf[PATH_MAX]; + unsigned i; + long count; + ssize_t n; + int fd, ret; + + c.args = &call; + fd = write_file_get_fd(test_file, t, sizeof(t)); + count = sizeof(buf); + for(i = 0; i < sizeof(enum ns_type); i++) + call.context.ns[i].type = NS_NONE; + call.nr = SYS_read; + call.args[0] = (void *)(long) fd; + call.args[1] = (void *)&buf; + call.args[2] = (void *)count; + ret = do_call(&c); + + ck_assert_int_eq(ret, 0); + ck_assert_msg(c.ret == count, "expect ret %ld to be %ld", c.ret, count); + ck_assert_str_eq(t, buf); +} +END_TEST + +START_TEST(test_with_getppid) +{ + struct act_call call; + struct arg_clone c; + char buf[PATH_MAX]; + unsigned i; + long pid = (long) getpid(); + int ret; + + for(i = 0; i < sizeof(enum ns_type); i++) + call.context.ns[i].type = NS_NONE; + call.nr = SYS_getppid; + c.args = &call; + ret = do_call(&c); + ck_assert_int_eq(ret, 0); + ck_assert_msg(c.ret == pid, "expect ret %ld to be equal to %ld", c.ret, pid); +} +END_TEST + +Suite *action_call_suite(void) +{ + Suite *s; + TCase *tactions; + + s = suite_create("Perform actions call"); + tactions = tcase_create("action calls"); + + tcase_add_test(tactions, test_with_getppid); + tcase_add_test(tactions, test_with_read); + tcase_add_test(tactions,test_with_open_read_ns); + + suite_add_tcase(s, tactions); + + return s; +} + +int main(void) +{ + int no_failed = 0; + Suite *s; + SRunner *runner; + + s = action_call_suite(); + runner = srunner_create(s); + + srunner_run_all(runner, CK_VERBOSE); + no_failed = srunner_ntests_failed(runner); + srunner_free(runner); + return (no_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} -- cgit v1.2.3