diff --git a/test/zdtm/static/seccomp_filter_threads.c b/test/zdtm/static/seccomp_filter_threads.c index a0e0b6472..b3fa6089d 100644 --- a/test/zdtm/static/seccomp_filter_threads.c +++ b/test/zdtm/static/seccomp_filter_threads.c @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __NR_seccomp # include @@ -18,6 +19,7 @@ #endif #include "zdtmtst.h" +#include "lock.h" #ifndef SECCOMP_SET_MODE_FILTER #define SECCOMP_SET_MODE_FILTER 1 @@ -32,7 +34,10 @@ const char *test_author = "Cyrill Gorcunov "; #ifdef __NR_seccomp -static task_waiter_t tw; +static long sys_gettid(void) { return syscall(__NR_gettid); } + +static futex_t *wait_rdy; +static futex_t *wait_run; int get_seccomp_mode(pid_t pid) { @@ -40,7 +45,7 @@ int get_seccomp_mode(pid_t pid) char buf[PATH_MAX]; sprintf(buf, "/proc/%d/status", pid); - f = fopen(buf, "r+"); + f = fopen(buf, "r"); if (!f) { pr_perror("fopen failed"); return -1; @@ -82,27 +87,76 @@ int filter_syscall(int syscall_nr, unsigned int flags) return 0; } +void tigger_ptrace(void) { ptrace(PTRACE_TRACEME); } +void trigger_prctl(void) { prctl(PR_SET_PDEATHSIG, 9, 0, 0, 0); } +void trigger_mincore(void) { mincore(NULL, 0, NULL); } + +#define gen_param(__syscall_nr, __trigger) \ +{ \ + .syscall_name = # __syscall_nr, \ + .syscall_nr = __syscall_nr, \ + .trigger = __trigger, \ +} + +struct { + char *syscall_name; + unsigned int syscall_nr; + void (*trigger)(void); +} pthread_seccomp_params[] = { + gen_param(__NR_ptrace, tigger_ptrace), + gen_param(__NR_prctl, trigger_prctl), + gen_param(__NR_mincore, trigger_mincore), +}; + +#define WAITER_VALS_OFFSET (ARRAY_SIZE(pthread_seccomp_params) * 2) + void *thread_main(void *arg) { - if (filter_syscall(__NR_ptrace, 0) < 0) + size_t nr = (long) arg; + + if (filter_syscall(pthread_seccomp_params[nr].syscall_nr, 0) < 0) pthread_exit((void *)1); - test_msg("__NR_ptrace filtered inside a sole thread\n"); + test_msg("%s filtered inside a sole thread %lu\n", + pthread_seccomp_params[nr].syscall_name, + sys_gettid()); - task_waiter_complete(&tw, 1); - task_waiter_wait4(&tw, 2); + futex_inc_and_wake(wait_rdy); + futex_wait_while_lt(wait_run, 1); - ptrace(PTRACE_TRACEME); + test_msg("Triggering %zu %s thread %lu\n", + nr, pthread_seccomp_params[nr].syscall_name, + sys_gettid()); + + pthread_seccomp_params[nr].trigger(); + + test_msg("Abnormal exit %zu thread %lu\n", nr, sys_gettid()); pthread_exit((void *)1); } int main(int argc, char ** argv) { int ret, mode, status; + size_t i; pid_t pid; test_init(argc, argv); - task_waiter_init(&tw); + + wait_rdy = mmap(NULL, sizeof(*wait_rdy), PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED, -1, 0); + wait_run = mmap(NULL, sizeof(*wait_rdy), PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED, -1, 0); + + if (wait_rdy == MAP_FAILED || wait_run == MAP_FAILED) { + pr_perror("mmap failed\n"); + exit(1); + } + + futex_init(wait_rdy); + futex_init(wait_run); + + futex_set(wait_rdy, 0); + futex_set(wait_run, 0); pid = fork(); if (pid < 0) { @@ -110,27 +164,37 @@ int main(int argc, char ** argv) return -1; } + if (pid == 0) { - pthread_t thread; + pthread_t thread[ARRAY_SIZE(pthread_seccomp_params)]; void *p = NULL; zdtm_seccomp = 1; - pthread_create(&thread, NULL, thread_main, NULL); - if (pthread_join(thread, &p) != 0) { - pr_perror("pthread_join"); - exit(1); + for (i = 0; i < ARRAY_SIZE(pthread_seccomp_params); i++) { + if (pthread_create(&thread[i], NULL, thread_main, (void *)i)) { + pr_perror("pthread_create"); + exit(1); + } } - syscall(__NR_exit, p); + for (i = 0; i < ARRAY_SIZE(pthread_seccomp_params); i++) { + test_msg("Waiting thread %zu\n", i); + if (pthread_join(thread[i], &p) != 0) { + pr_perror("pthread_join"); + exit(1); + } + } + + syscall(__NR_exit, 0); } - task_waiter_wait4(&tw, 1); + futex_wait_until(wait_rdy, ARRAY_SIZE(pthread_seccomp_params)); test_daemon(); test_waitsig(); - task_waiter_complete(&tw, 2); + futex_inc_and_wake(wait_run); mode = get_seccomp_mode(pid); if (mode != SECCOMP_MODE_DISABLED) {