aboutgitcodelistschat:MatrixIRC
path: root/tests
diff options
context:
space:
mode:
authorAlice Frosi <afrosi@redhat.com>2023-01-24 17:05:32 +0100
committerAlice Frosi <afrosi@redhat.com>2023-02-15 13:10:01 +0100
commit12d77297b590beb6688e32c142ce13d91e30c51a (patch)
tree464c3390f1e660d5880f9b9bf022e8580af8bc86 /tests
parent2a0e9e1d8ebabf71299c7027d4577b5c709d6ea5 (diff)
downloadseitan-12d77297b590beb6688e32c142ce13d91e30c51a.tar
seitan-12d77297b590beb6688e32c142ce13d91e30c51a.tar.gz
seitan-12d77297b590beb6688e32c142ce13d91e30c51a.tar.bz2
seitan-12d77297b590beb6688e32c142ce13d91e30c51a.tar.lz
seitan-12d77297b590beb6688e32c142ce13d91e30c51a.tar.xz
seitan-12d77297b590beb6688e32c142ce13d91e30c51a.tar.zst
seitan-12d77297b590beb6688e32c142ce13d91e30c51a.zip
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 <afrosi@redhat.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/unit/Makefile7
-rw-r--r--tests/unit/test_action_call.c225
2 files changed, 231 insertions, 1 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sched.h>
+#include <sys/wait.h>
+#include <sys/syscall.h>
+
+#include <check.h>
+
+#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;
+}