aboutsummaryrefslogtreecommitdiff
path: root/src/pseccomp.c
diff options
context:
space:
mode:
authorlns <matzeton@googlemail.com>2018-04-11 14:28:18 +0200
committerToni Uhlig <matzeton@googlemail.com>2018-06-13 18:23:43 +0200
commitf2f11e477a489ac25a4c4be064eddc26fc9d677c (patch)
treed4f679146a61b28056e772e30570c53fb4721b80 /src/pseccomp.c
parentebabaa69c0a3ba992895c7a66729e81e0923d5f1 (diff)
POTD skeleton.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'src/pseccomp.c')
-rw-r--r--src/pseccomp.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/src/pseccomp.c b/src/pseccomp.c
new file mode 100644
index 0000000..a08bc11
--- /dev/null
+++ b/src/pseccomp.c
@@ -0,0 +1,223 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <sys/prctl.h>
+#ifdef HAVE_VALGRIND
+#include <valgrind.h>
+#endif
+
+#include "pseccomp.h"
+#include "log.h"
+#include "utils.h"
+
+static int pseccomp_using_valgrind(void);
+
+static const int minimum_disabled_syscalls[] = {
+ SCMP_SYS(reboot),
+ SCMP_SYS(mount),
+ SCMP_SYS(umount), SCMP_SYS(umount2),
+ SCMP_SYS(ptrace),
+ SCMP_SYS(kexec_load),
+ SCMP_SYS(kexec_file_load),
+ SCMP_SYS(open_by_handle_at),
+ SCMP_SYS(create_module),
+ SCMP_SYS(init_module),
+ SCMP_SYS(finit_module),
+ SCMP_SYS(delete_module),
+ SCMP_SYS(iopl),
+ SCMP_SYS(swapon),
+ SCMP_SYS(swapoff),
+ SCMP_SYS(syslog),
+ SCMP_SYS(nice),
+ SCMP_SYS(kcmp),
+ SCMP_SYS(unshare),
+ SCMP_SYS(setns),
+ SCMP_SYS(pivot_root),
+ SCMP_SYS(chroot),
+ SCMP_SYS(fchdir),
+ SCMP_SYS(capset),
+ SCMP_SYS(mknod),
+ SCMP_SYS(mknodat)
+};
+
+static const int default_allowed_syscalls[] = {
+ SCMP_SYS(restart_syscall),
+ SCMP_SYS(signalfd), SCMP_SYS(signalfd4),
+ SCMP_SYS(rt_sigreturn), SCMP_SYS(rt_sigprocmask),
+ SCMP_SYS(rt_sigaction), SCMP_SYS(time), SCMP_SYS(nanosleep),
+ SCMP_SYS(clock_gettime), SCMP_SYS(set_tid_address),
+ SCMP_SYS(exit), SCMP_SYS(exit_group),
+ SCMP_SYS(read), SCMP_SYS(readv), SCMP_SYS(write), SCMP_SYS(writev),
+ SCMP_SYS(fcntl), SCMP_SYS(fcntl64),
+ SCMP_SYS(close), SCMP_SYS(wait4),
+ SCMP_SYS(sigprocmask), SCMP_SYS(tgkill), SCMP_SYS(gettid), SCMP_SYS(set_tls),
+ SCMP_SYS(fork), SCMP_SYS(clone), SCMP_SYS(execve),
+ SCMP_SYS(socket), SCMP_SYS(bind), SCMP_SYS(setsockopt), SCMP_SYS(shutdown),
+ SCMP_SYS(listen), SCMP_SYS(connect), SCMP_SYS(getsockname),
+ SCMP_SYS(accept), SCMP_SYS(sendto), SCMP_SYS(recvmsg), SCMP_SYS(recvfrom),
+ SCMP_SYS(epoll_create1), SCMP_SYS(epoll_ctl), SCMP_SYS(epoll_pwait),
+ SCMP_SYS(poll), SCMP_SYS(pipe), SCMP_SYS(pipe2),
+ SCMP_SYS(set_robust_list), SCMP_SYS(getrlimit),
+ SCMP_SYS(seccomp), SCMP_SYS(getrusage),
+ SCMP_SYS(prlimit64),
+ SCMP_SYS(prctl), SCMP_SYS(mmap), SCMP_SYS(mmap2), SCMP_SYS(brk), SCMP_SYS(madvise),
+ SCMP_SYS(mlock), SCMP_SYS(getrandom),
+ SCMP_SYS(mprotect), SCMP_SYS(munmap), SCMP_SYS(futex),
+ /* operations on files */
+ SCMP_SYS(open), SCMP_SYS(openat),
+ SCMP_SYS(unlink), SCMP_SYS(fstat), SCMP_SYS(fstat64), SCMP_SYS(access),
+ SCMP_SYS(_llseek), SCMP_SYS(lseek), SCMP_SYS(stat), SCMP_SYS(stat64),
+ SCMP_SYS(readlink), SCMP_SYS(getcwd),
+ SCMP_SYS(lstat), SCMP_SYS(sysinfo),
+ /* operations on user/group */
+ SCMP_SYS(setuid), SCMP_SYS(setuid32), SCMP_SYS(setgid), SCMP_SYS(setgid32),
+ SCMP_SYS(setresuid), SCMP_SYS(setresuid32), SCMP_SYS(setresgid), SCMP_SYS(setresgid32),
+ SCMP_SYS(getuid), SCMP_SYS(getuid32), SCMP_SYS(geteuid), SCMP_SYS(geteuid32),
+ SCMP_SYS(getgid), SCMP_SYS(getgid32), SCMP_SYS(getegid), SCMP_SYS(getegid),
+ SCMP_SYS(getgroups), SCMP_SYS(getdents),
+ /* operations on processes */
+ SCMP_SYS(getpgrp), SCMP_SYS(setpgid), SCMP_SYS(getpid), SCMP_SYS(getppid),
+ SCMP_SYS(kill),
+ /* other */
+ SCMP_SYS(unshare), SCMP_SYS(setns),
+ SCMP_SYS(chroot), SCMP_SYS(chdir), SCMP_SYS(mount), SCMP_SYS(umount2),
+ SCMP_SYS(mknod), SCMP_SYS(mkdir), SCMP_SYS(rmdir),
+ SCMP_SYS(statfs), SCMP_SYS(ioctl),
+ SCMP_SYS(umask), SCMP_SYS(chown), SCMP_SYS(chmod), SCMP_SYS(setsid),
+ SCMP_SYS(dup), SCMP_SYS(dup2), SCMP_SYS(dup3),
+ SCMP_SYS(sethostname), SCMP_SYS(uname), SCMP_SYS(arch_prctl)
+};
+
+static const int protocol_disabled_syscalls[] = {
+ SCMP_SYS(execve), SCMP_SYS(execveat)
+};
+
+static const int jail_allowed_syscalls[] = {
+ SCMP_SYS(restart_syscall),
+ SCMP_SYS(signalfd), SCMP_SYS(signalfd4),
+ SCMP_SYS(rt_sigreturn), SCMP_SYS(rt_sigprocmask),
+ SCMP_SYS(rt_sigaction), SCMP_SYS(time), SCMP_SYS(nanosleep),
+ SCMP_SYS(clock_gettime), SCMP_SYS(set_tid_address),
+ SCMP_SYS(exit), SCMP_SYS(exit_group),
+ SCMP_SYS(read), SCMP_SYS(write), SCMP_SYS(writev),
+ SCMP_SYS(fcntl), SCMP_SYS(fcntl64),
+ SCMP_SYS(close), SCMP_SYS(wait4),
+ SCMP_SYS(sigprocmask), SCMP_SYS(tgkill), SCMP_SYS(gettid), SCMP_SYS(set_tls),
+ SCMP_SYS(fork), SCMP_SYS(clone), SCMP_SYS(execve),
+ SCMP_SYS(mmap), SCMP_SYS(mmap2), SCMP_SYS(brk), SCMP_SYS(madvise),
+ SCMP_SYS(mprotect), SCMP_SYS(munmap), SCMP_SYS(futex),
+ SCMP_SYS(open), SCMP_SYS(openat), SCMP_SYS(fstat), SCMP_SYS(fstat64), SCMP_SYS(access),
+ SCMP_SYS(poll), SCMP_SYS(pipe), SCMP_SYS(pipe2),
+ SCMP_SYS(lseek), SCMP_SYS(stat), SCMP_SYS(stat64), SCMP_SYS(readlink), SCMP_SYS(getcwd),
+ SCMP_SYS(lstat), SCMP_SYS(sysinfo),
+ SCMP_SYS(setuid), SCMP_SYS(setgid),
+ SCMP_SYS(setresuid), SCMP_SYS(setresgid),
+ SCMP_SYS(getuid), SCMP_SYS(geteuid), SCMP_SYS(getgid), SCMP_SYS(getegid),
+ SCMP_SYS(getgroups), SCMP_SYS(getdents),
+ SCMP_SYS(getpgrp), SCMP_SYS(setpgid), SCMP_SYS(getpid), SCMP_SYS(getppid),
+ SCMP_SYS(kill),
+ SCMP_SYS(chdir), SCMP_SYS(mount),
+ SCMP_SYS(umount2),
+ SCMP_SYS(ioctl),
+ SCMP_SYS(dup), SCMP_SYS(dup2), SCMP_SYS(dup3),
+ SCMP_SYS(sethostname), SCMP_SYS(uname), SCMP_SYS(arch_prctl)
+};
+
+
+static int pseccomp_using_valgrind(void)
+{
+#ifdef HAVE_VALGRIND
+ if (RUNNING_ON_VALGRIND) {
+ W("%s", "SECCOMP: running on valgrind, disabled");
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+int pseccomp_init(pseccomp_ctx **ctx, unsigned flags)
+{
+ assert(ctx);
+
+ if (!*ctx)
+ *ctx = (pseccomp_ctx *) malloc(sizeof(**ctx));
+ assert(*ctx);
+
+ memset(*ctx, 0, sizeof(**ctx));
+ (*ctx)->sfilter = seccomp_init(
+ (flags & PS_ALLOW || flags & PS_MINIMUM ?
+ SCMP_ACT_ALLOW : SCMP_ACT_ERRNO(EINVAL))
+ );
+
+ return 0;
+}
+
+void pseccomp_free(pseccomp_ctx **ctx)
+{
+ assert(ctx && *ctx);
+
+ seccomp_release((*ctx)->sfilter);
+ free(*ctx);
+ (*ctx) = NULL;
+}
+
+int pseccomp_set_immutable(void)
+{
+ if (prctl(PR_SET_DUMPABLE, 0) &&
+ prctl(PR_SET_NO_NEW_PRIVS, 1))
+ {
+ FATAL("%s", "PR_SET_NO_NEW_PRIVS, PR_SET_DUMPABLE");
+ }
+
+ return 0;
+}
+
+int pseccomp_default_rules(pseccomp_ctx *ctx)
+{
+ size_t i;
+
+ if (pseccomp_using_valgrind())
+ return 0;
+
+ if (ctx->flags & PS_MINIMUM) {
+ for (i = 0; i < SIZEOF(minimum_disabled_syscalls); ++i)
+ seccomp_rule_add(ctx->sfilter, SCMP_ACT_ERRNO(EINVAL),
+ minimum_disabled_syscalls[i], 0);
+ } else {
+ for (i = 0; i < SIZEOF(default_allowed_syscalls); ++i)
+ seccomp_rule_add(ctx->sfilter, SCMP_ACT_ALLOW,
+ default_allowed_syscalls[i], 0);
+ }
+
+ return seccomp_load(ctx->sfilter);
+}
+
+int pseccomp_protocol_rules(pseccomp_ctx *ctx)
+{
+ size_t i;
+
+ if (pseccomp_using_valgrind())
+ return 0;
+
+ for (i = 0; i < SIZEOF(protocol_disabled_syscalls); ++i)
+ seccomp_rule_add(ctx->sfilter, SCMP_ACT_ERRNO(EINVAL),
+ protocol_disabled_syscalls[i], 0);
+
+ return seccomp_load(ctx->sfilter);
+}
+
+int pseccomp_jail_rules(pseccomp_ctx *ctx)
+{
+ size_t i;
+
+ if (pseccomp_using_valgrind())
+ return 0;
+
+ for (i = 0; i < SIZEOF(jail_allowed_syscalls); ++i)
+ seccomp_rule_add(ctx->sfilter, SCMP_ACT_ALLOW,
+ jail_allowed_syscalls[i], 0);
+
+ return seccomp_load(ctx->sfilter);
+}