mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-04 00:05:26 +00:00
seccomp: test, seccomp_filter_threads -- Use multiple threads
Andrew proposed the test which actually triggered the issue in current seccomp series, put it into a regular basis. Suggested-by: Andrey Vagin <avagin@virtuozzo.com> Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
committed by
Andrei Vagin
parent
064cafa80c
commit
cf74c9fed3
@@ -9,6 +9,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#ifdef __NR_seccomp
|
#ifdef __NR_seccomp
|
||||||
# include <linux/seccomp.h>
|
# include <linux/seccomp.h>
|
||||||
@@ -18,6 +19,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "zdtmtst.h"
|
#include "zdtmtst.h"
|
||||||
|
#include "lock.h"
|
||||||
|
|
||||||
#ifndef SECCOMP_SET_MODE_FILTER
|
#ifndef SECCOMP_SET_MODE_FILTER
|
||||||
#define SECCOMP_SET_MODE_FILTER 1
|
#define SECCOMP_SET_MODE_FILTER 1
|
||||||
@@ -32,7 +34,10 @@ const char *test_author = "Cyrill Gorcunov <gorcunov@openvz.org>";
|
|||||||
|
|
||||||
#ifdef __NR_seccomp
|
#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)
|
int get_seccomp_mode(pid_t pid)
|
||||||
{
|
{
|
||||||
@@ -40,7 +45,7 @@ int get_seccomp_mode(pid_t pid)
|
|||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
sprintf(buf, "/proc/%d/status", pid);
|
sprintf(buf, "/proc/%d/status", pid);
|
||||||
f = fopen(buf, "r+");
|
f = fopen(buf, "r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
pr_perror("fopen failed");
|
pr_perror("fopen failed");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -82,27 +87,76 @@ int filter_syscall(int syscall_nr, unsigned int flags)
|
|||||||
return 0;
|
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)
|
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);
|
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);
|
futex_inc_and_wake(wait_rdy);
|
||||||
task_waiter_wait4(&tw, 2);
|
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);
|
pthread_exit((void *)1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char ** argv)
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
int ret, mode, status;
|
int ret, mode, status;
|
||||||
|
size_t i;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
test_init(argc, argv);
|
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();
|
pid = fork();
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
@@ -110,27 +164,37 @@ int main(int argc, char ** argv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
pthread_t thread;
|
pthread_t thread[ARRAY_SIZE(pthread_seccomp_params)];
|
||||||
void *p = NULL;
|
void *p = NULL;
|
||||||
|
|
||||||
zdtm_seccomp = 1;
|
zdtm_seccomp = 1;
|
||||||
|
|
||||||
pthread_create(&thread, NULL, thread_main, NULL);
|
for (i = 0; i < ARRAY_SIZE(pthread_seccomp_params); i++) {
|
||||||
if (pthread_join(thread, &p) != 0) {
|
if (pthread_create(&thread[i], NULL, thread_main, (void *)i)) {
|
||||||
pr_perror("pthread_join");
|
pr_perror("pthread_create");
|
||||||
exit(1);
|
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_daemon();
|
||||||
test_waitsig();
|
test_waitsig();
|
||||||
|
|
||||||
task_waiter_complete(&tw, 2);
|
futex_inc_and_wake(wait_run);
|
||||||
mode = get_seccomp_mode(pid);
|
mode = get_seccomp_mode(pid);
|
||||||
|
|
||||||
if (mode != SECCOMP_MODE_DISABLED) {
|
if (mode != SECCOMP_MODE_DISABLED) {
|
||||||
|
Reference in New Issue
Block a user