Commit 1fa30840 authored by Tycho Andersen's avatar Tycho Andersen Committed by Pavel Emelyanov

add a `criu check` test for PTRACE_O_SUSPEND_SECCOMP

v2: actually set ret = -1 on failure
v3: add a --feature option for suspend_seccomp (and make this patch 1,
    since the tests depend on it now)
Signed-off-by: 's avatarTycho Andersen <tycho.andersen@canonical.com>
Acked-by: 's avatarAndrew Vagin <avagin@odin.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent fa3c94d5
...@@ -529,17 +529,15 @@ static int check_sigqueuinfo() ...@@ -529,17 +529,15 @@ static int check_sigqueuinfo()
return 0; return 0;
} }
static int check_ptrace_peeksiginfo() static pid_t fork_and_ptrace_attach(void)
{ {
struct ptrace_peeksiginfo_args arg; pid_t pid;
siginfo_t siginfo;
pid_t pid, ret = 0;
k_rtsigset_t mask;
pid = fork(); pid = fork();
if (pid < 0) if (pid < 0) {
pr_perror("fork"); pr_perror("fork");
else if (pid == 0) { return -1;
} else if (pid == 0) {
while (1) while (1)
sleep(1000); sleep(1000);
exit(1); exit(1);
...@@ -547,12 +545,26 @@ static int check_ptrace_peeksiginfo() ...@@ -547,12 +545,26 @@ static int check_ptrace_peeksiginfo()
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) { if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
pr_perror("Unable to ptrace the child"); pr_perror("Unable to ptrace the child");
ret = -1; kill(pid, SIGKILL);
goto out; return -1;
} }
waitpid(pid, NULL, 0); waitpid(pid, NULL, 0);
return pid;
}
static int check_ptrace_peeksiginfo()
{
struct ptrace_peeksiginfo_args arg;
siginfo_t siginfo;
pid_t pid, ret = 0;
k_rtsigset_t mask;
pid = fork_and_ptrace_attach();
if (pid < 0)
return -1;
arg.flags = 0; arg.flags = 0;
arg.off = 0; arg.off = 0;
arg.nr = 1; arg.nr = 1;
...@@ -567,7 +579,33 @@ static int check_ptrace_peeksiginfo() ...@@ -567,7 +579,33 @@ static int check_ptrace_peeksiginfo()
ret = -1; ret = -1;
} }
out: kill(pid, SIGKILL);
return ret;
}
static int check_ptrace_suspend_seccomp(void)
{
pid_t pid;
int ret = 0;
if (opts.check_ms_kernel) {
pr_warn("Skipping PTRACE_O_SUSPEND_SECCOMP check\n");
return 0;
}
pid = fork_and_ptrace_attach();
if (pid < 0)
return -1;
if (ptrace(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_SUSPEND_SECCOMP) < 0) {
if (errno == EINVAL) {
pr_err("Kernel doesn't support PTRACE_O_SUSPEND_SECCOMP\n");
} else {
pr_perror("couldn't suspend seccomp");
}
ret = -1;
}
kill(pid, SIGKILL); kill(pid, SIGKILL);
return ret; return ret;
} }
...@@ -734,6 +772,7 @@ int cr_check(void) ...@@ -734,6 +772,7 @@ int cr_check(void)
ret |= check_ipc(); ret |= check_ipc();
ret |= check_sigqueuinfo(); ret |= check_sigqueuinfo();
ret |= check_ptrace_peeksiginfo(); ret |= check_ptrace_peeksiginfo();
ret |= check_ptrace_suspend_seccomp();
ret |= check_mem_dirty_track(); ret |= check_mem_dirty_track();
ret |= check_posix_timers(); ret |= check_posix_timers();
ret |= check_tun_cr(0); ret |= check_tun_cr(0);
...@@ -794,6 +833,8 @@ int check_add_feature(char *feat) ...@@ -794,6 +833,8 @@ int check_add_feature(char *feat)
chk_feature = check_userns; chk_feature = check_userns;
else if (!strcmp(feat, "fdinfo_lock")) else if (!strcmp(feat, "fdinfo_lock"))
chk_feature = check_fdinfo_lock; chk_feature = check_fdinfo_lock;
else if (!strcmp(feat, "seccomp_suspend"))
chk_feature = check_ptrace_suspend_seccomp;
else { else {
pr_err("Unknown feature %s\n", feat); pr_err("Unknown feature %s\n", feat);
return -1; return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment