[CRIU] [PATCH 09/10] seccomp: test, seccomp_filter_threads -- Use multiple threads
Cyrill Gorcunov
gorcunov at gmail.com
Mon May 7 11:42:49 MSK 2018
Andrew proposed the test which actually triggered the issue
in current seccomp series, put it into a regular basis.
Suggested-by: Andrey Vagin <avagin at virtuozzo.com>
Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
test/zdtm/static/seccomp_filter_threads.c | 96 +++++++++++++++++++++++++------
1 file changed, 80 insertions(+), 16 deletions(-)
diff --git a/test/zdtm/static/seccomp_filter_threads.c b/test/zdtm/static/seccomp_filter_threads.c
index a0e0b6472d1a..b3fa6089d0c9 100644
--- a/test/zdtm/static/seccomp_filter_threads.c
+++ b/test/zdtm/static/seccomp_filter_threads.c
@@ -9,6 +9,7 @@
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/syscall.h>
+#include <sys/mman.h>
#ifdef __NR_seccomp
# include <linux/seccomp.h>
@@ -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 <gorcunov at openvz.org>";
#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());
+
+ futex_inc_and_wake(wait_rdy);
+ futex_wait_while_lt(wait_run, 1);
+
+ test_msg("Triggering %zu %s thread %lu\n",
+ nr, pthread_seccomp_params[nr].syscall_name,
+ sys_gettid());
- task_waiter_complete(&tw, 1);
- task_waiter_wait4(&tw, 2);
+ pthread_seccomp_params[nr].trigger();
- ptrace(PTRACE_TRACEME);
+ 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);
+ }
+ }
+
+ 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, p);
+ 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) {
--
2.14.3
More information about the CRIU
mailing list