aboutgitcodelistschat:MatrixIRC
path: root/tests/unit/test_operations.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit/test_operations.c')
-rw-r--r--tests/unit/test_operations.c177
1 files changed, 5 insertions, 172 deletions
diff --git a/tests/unit/test_operations.c b/tests/unit/test_operations.c
index c60fa4f..bb098b8 100644
--- a/tests/unit/test_operations.c
+++ b/tests/unit/test_operations.c
@@ -28,187 +28,17 @@
#include "gluten.h"
#include "operations.h"
#include "common.h"
-#include "util.h"
+#include "testutil.h"
#define MAX_TEST_PATH 250
-struct args_target {
- long ret;
- int err;
- bool check_fd;
- bool open_path;
- int fd;
- int nr;
- void *args[6];
-};
-
-struct seccomp_notif req;
-int notifyfd;
-struct args_target *at;
-int pipefd[2];
-pid_t pid;
-char path[] = "/tmp/test-seitan";
-
-uint16_t tmp_data[TMP_DATA_SIZE];
-
-static int install_notification_filter(int nr)
-{
- int fd;
- /* filter a single syscall for the tests */
- struct sock_filter filter[] = {
- BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
- (offsetof(struct seccomp_data, arch))),
- BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SEITAN_AUDIT_ARCH, 0, 3),
- BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
- (offsetof(struct seccomp_data, nr))),
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1),
- BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_USER_NOTIF),
- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW),
- };
- return install_filter(
- &filter, (unsigned short)(sizeof(filter) / sizeof(filter[0])));
-}
-
-static int create_test_fd()
-{
- return open("/tmp", O_RDWR | O_TMPFILE);
-}
-
-static int target()
-{
- int buf = 0;
- if (install_notification_filter(at->nr) < 0) {
- return -1;
- }
-
- at->ret = syscall(at->nr, at->args[0], at->args[1], at->args[2],
- at->args[3], at->args[4], at->args[5]);
- at->err = errno;
- if (at->open_path) {
- if ((at->fd = open(path, O_CREAT | O_RDONLY)) < 0) {
- perror("open");
- return -1;
- }
- }
- if (at->check_fd)
- read(pipefd[0], &buf, 1);
-
- close(pipefd[0]);
-
- write(pipefd[1], &buf, 1);
- close(pipefd[1]);
- exit(0);
-}
-
-static pid_t do_clone(int (*fn)(void *), void *arg)
-{
- char stack[STACK_SIZE];
- pid_t child;
- int flags = SIGCHLD;
-
- child = clone(fn, stack + sizeof(stack), flags, arg);
- if (child == -1) {
- perror("clone");
- return -1;
- }
- return child;
-}
-
-int get_fd_notifier(pid_t pid)
-{
- char path[PATH_MAX + 1];
- int pidfd, notifier;
- int fd = -1;
-
- snprintf(path, sizeof(path), "/proc/%d/fd", pid);
- while (fd < 0) {
- sleep(2);
- fd = find_fd_seccomp_notifier(path);
- }
- ck_assert_int_ge(fd, 0);
- pidfd = syscall(SYS_pidfd_open, pid, 0);
- ck_assert_msg(pidfd >= 0, strerror(errno));
- sleep(1);
- notifier = syscall(SYS_pidfd_getfd, pidfd, fd, 0);
- ck_assert_msg(notifier >= 0, strerror(errno));
- return notifier;
-}
-
-static void check_target_result(long ret, int err, bool ignore_ret)
-{
- int buf;
-
- read(pipefd[0], &buf, 1);
- if (!ignore_ret)
- ck_assert_msg(at->ret == ret,
- "expect return value %ld to be equal to %ld",
- at->ret, ret);
- ck_assert_int_eq(at->err, err);
- ck_assert_int_eq(close(pipefd[0]), 0);
-}
-
-void target_exit()
-{
- int status;
-
- waitpid(-1, &status, WUNTRACED | WNOHANG);
- if (WEXITSTATUS(status) != 0) {
- fprintf(stderr, "target process exited with an error\n");
- exit(-1);
- }
-}
-
-static bool has_fd(int pid, int fd)
-{
- char path[PATH_MAX + 1];
-
- snprintf(path, sizeof(path), "/proc/%d/fd/%d", pid, fd);
- return access(path, F_OK) == 0;
-}
-
-static void check_target_fd(int pid, int fd)
-{
- int buf = 0;
-
- ck_assert(has_fd(pid, fd));
- write(pipefd[1], &buf, 1);
- close(pipefd[1]);
-}
-
-void setup()
-{
- int ret;
-
- signal(SIGCHLD, target_exit);
- ck_assert_int_ne(pipe(pipefd), -1);
- pid = do_clone(target, NULL);
- ck_assert_int_ge(pid, 0);
-
- /* Use write pipe to sync the target for checking the existance of the fd */
- if (!at->check_fd)
- ck_assert_int_ne(close(pipefd[1]), -1);
-
- notifyfd = get_fd_notifier(pid);
-
- memset(&req, 0, sizeof(req));
- ret = ioctl(notifyfd, SECCOMP_IOCTL_NOTIF_RECV, &req);
- ck_assert_msg(ret == 0, strerror(errno));
- ck_assert_msg((req.data).nr == at->nr, "filter syscall nr: %d",
- (req.data).nr);
-}
-
-void teardown()
-{
- if (at != NULL)
- munmap(at, sizeof(struct args_target));
-}
-
void setup_without_fd()
{
at = mmap(NULL, sizeof(struct args_target), PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
at->check_fd = false;
at->nr = __NR_getpid;
+ at->install_filter = install_notification_filter;
setup();
}
void setup_fd()
@@ -217,6 +47,7 @@ void setup_fd()
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
at->check_fd = true;
at->nr = __NR_getpid;
+ at->install_filter = install_notification_filter;
setup();
}
@@ -226,6 +57,7 @@ void setup_path()
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
at->open_path = true;
at->nr = __NR_getpid;
+ at->install_filter = install_notification_filter;
setup();
}
@@ -248,6 +80,7 @@ void setup_target_connect()
at->args[0] = (void *)(long)fd;
at->args[1] = (void *)&addr;
at->args[2] = (void *)(long)len;
+ at->install_filter = install_notification_filter;
setup();
}