[CRIU] [PATCH 4/7] check: add a check for seccomp filters c/r
Tycho Andersen
tycho.andersen at canonical.com
Tue Nov 3 22:04:55 PST 2015
Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
cr-check.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 60 insertions(+), 3 deletions(-)
diff --git a/cr-check.c b/cr-check.c
index 85940f3..d8be470 100644
--- a/cr-check.c
+++ b/cr-check.c
@@ -12,6 +12,10 @@
#include <fcntl.h>
#include <signal.h>
#include <linux/if.h>
+#include <linux/filter.h>
+#include <linux/bpf.h>
+#include <linux/seccomp.h>
+#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <sys/mman.h>
@@ -525,7 +529,7 @@ static int check_sigqueuinfo()
return 0;
}
-static pid_t fork_and_ptrace_attach(void)
+static pid_t fork_and_ptrace_attach(int (*child_setup)(void))
{
pid_t pid;
@@ -534,6 +538,9 @@ static pid_t fork_and_ptrace_attach(void)
pr_perror("fork");
return -1;
} else if (pid == 0) {
+ if (child_setup && child_setup() != 0)
+ exit(1);
+
while (1)
sleep(1000);
exit(1);
@@ -557,7 +564,7 @@ static int check_ptrace_peeksiginfo()
pid_t pid, ret = 0;
k_rtsigset_t mask;
- pid = fork_and_ptrace_attach();
+ pid = fork_and_ptrace_attach(NULL);
if (pid < 0)
return -1;
@@ -589,7 +596,7 @@ static int check_ptrace_suspend_seccomp(void)
return 0;
}
- pid = fork_and_ptrace_attach();
+ pid = fork_and_ptrace_attach(NULL);
if (pid < 0)
return -1;
@@ -606,6 +613,53 @@ static int check_ptrace_suspend_seccomp(void)
return ret;
}
+static int setup_seccomp_filter(void)
+{
+ struct sock_filter filter[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)),
+ /* Allow all syscalls except ptrace */
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ptrace, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
+ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+ };
+
+ struct sock_fprog bpf_prog = {
+ .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+ .filter = filter,
+ };
+
+ if (sys_prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, (long) &bpf_prog, 0, 0) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int check_ptrace_dump_seccomp_filters(void)
+{
+ pid_t pid;
+ int ret = 0, fd;
+
+ if (opts.check_ms_kernel) {
+ pr_warn("Skipping PTRACE_SECCOMP_GET_FILTER check");
+ return 0;
+ }
+
+ pid = fork_and_ptrace_attach(setup_seccomp_filter);
+ if (pid < 0)
+ return -1;
+
+ fd = ptrace(PTRACE_SECCOMP_GET_FILTER, pid, NULL, 0);
+ if (fd < 0) {
+ ret = -1;
+ pr_err("Dumping seccomp filters not supported\n");
+ } else {
+ close(fd);
+ }
+
+ kill(pid, SIGKILL);
+ return ret;
+}
+
static int check_mem_dirty_track(void)
{
if (kerndat_get_dirty_track() < 0)
@@ -796,6 +850,7 @@ int cr_check(void)
ret |= check_sigqueuinfo();
ret |= check_ptrace_peeksiginfo();
ret |= check_ptrace_suspend_seccomp();
+ ret |= check_ptrace_dump_seccomp_filters();
ret |= check_mem_dirty_track();
ret |= check_posix_timers();
ret |= check_tun_cr(0);
@@ -859,6 +914,8 @@ int check_add_feature(char *feat)
chk_feature = check_fdinfo_lock;
else if (!strcmp(feat, "seccomp_suspend"))
chk_feature = check_ptrace_suspend_seccomp;
+ else if (!strcmp(feat, "seccomp_filters"))
+ chk_feature = check_ptrace_dump_seccomp_filters;
else {
pr_err("Unknown feature %s\n", feat);
return -1;
--
2.5.0
More information about the CRIU
mailing list