diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2018-08-30 23:51:59 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2018-08-30 23:51:59 +0200 |
commit | d9f5862f0c29de47940785c84109fab9fa69dbb5 (patch) | |
tree | 4775e50e6b2814540888ed1059e04dba5af97840 | |
parent | 6cd6fc810c759b17ab1d8eff648d22b38f1df230 (diff) |
enable SECCOMP text/bpf export
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | src/options.c | 4 | ||||
-rw-r--r-- | src/options.h | 2 | ||||
-rw-r--r-- | src/pseccomp.c | 51 |
4 files changed, 61 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac index 04370cb..3240fec 100644 --- a/configure.ac +++ b/configure.ac @@ -119,9 +119,9 @@ AC_CHECK_HEADERS([stdio.h ctype.h assert.h sched.h signal.h time.h errno.h pwd.h [ AC_MSG_ERROR([required std header not available]) ]) dnl Check for system specific header files -AC_CHECK_HEADERS([linux/capability.h linux/securebits.h sys/signalfd.h sys/wait.h sys/ioctl.h net/if.h netinet/in.h libgen.h], [], +AC_CHECK_HEADERS([linux/capability.h linux/securebits.h sys/signalfd.h sys/wait.h sys/ioctl.h net/if.h netinet/in.h libgen.h sys/prctl.h], [], [ AC_MSG_ERROR([required system specific header not available]) ]) -AC_CHECK_HEADERS([libutil.h pthread.h semaphore.h syslog.h sys/prctl.h linux/limits.h \ +AC_CHECK_HEADERS([libutil.h pthread.h semaphore.h syslog.h linux/limits.h \ sys/uio.h poll.h sys/epoll.h sys/sysmacros.h sys/mount.h sys/mman.h \ util.h execinfo.h syslog.h]) @@ -450,5 +450,8 @@ AC_DEFINE_UNQUOTED([POTD_RODIR], ["$potd_rodir"], potd_rofile="/var/run/potd-rofile" AC_DEFINE_UNQUOTED([POTD_ROFILE], ["$potd_rofile"], [default path to a file for readonly bind mounts]) +potd_dbgdir="/tmp/potd-debug" +AC_DEFINE_UNQUOTED([POTD_DBGDIR], ["$potd_dbgdir"], + [default path to a directory for debugging output]) AC_OUTPUT(Makefile src/Makefile) diff --git a/src/options.c b/src/options.c index 45efcad..def0b40 100644 --- a/src/options.c +++ b/src/options.c @@ -140,6 +140,10 @@ static struct opt options[OPT_MAX+1] = { "mount, umount, ptrace, kernel module syscalls\n" "and some io syscalls\n" "(use this if you acknowledge errors on some platforms e.g. OpenWrt)\n"), + OPT_NOARG("seccomp-debug", "generate seccomp debug output\n", "generate seccomp bpf text/binary files useful\n" + "for debugging rulesets\n"), + OPT(OT_STR, .str = POTD_DBGDIR, "dbgdir", "debug directory\n", + "set an optional directory to output debug files\n"), OPT_NOARG("test", "test essential daemon functions and exit\n", NULL), OPT_NOARG("help", "this\n", NULL), diff --git a/src/options.h b/src/options.h index 0138344..456779b 100644 --- a/src/options.h +++ b/src/options.h @@ -50,6 +50,8 @@ typedef enum opt_name { OPT_CHUSER, OPT_CHGROUP, OPT_SECCOMP_MINIMAL, + OPT_SECCOMP_DEBUG, + OPT_DEBUG_DIR, OPT_RUNTEST, OPT_HELP, diff --git a/src/pseccomp.c b/src/pseccomp.c index 248f1cf..79b0627 100644 --- a/src/pseccomp.c +++ b/src/pseccomp.c @@ -35,16 +35,24 @@ #include "config.h" #endif +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> #include <assert.h> +#include <sys/stat.h> #include <sys/prctl.h> +#include <limits.h> #ifdef HAVE_VALGRIND #include <valgrind.h> #endif #include "pseccomp.h" +#include "options.h" #include "log.h" #include "utils.h" +static void pseccomp_export(const char *path, pseccomp_ctx *ctx, int as_text); +static void pseccomp_dbg(const char *ruleset_name, pseccomp_ctx *ctx); static int pseccomp_using_valgrind(void); static const int minimum_disabled_syscalls[] = { @@ -166,6 +174,38 @@ static const int jail_allowed_syscalls[] = { }; +static void pseccomp_export(const char *path, pseccomp_ctx *ctx, int as_text) +{ + int fd; + + errno = 0; + fd = open(path, O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC); + if (fd < 0) + FATAL("Open seccomp debug file '%s'", path); + if (as_text) + seccomp_export_pfc(ctx->sfilter, fd); + else + seccomp_export_bpf(ctx->sfilter, fd); + close(fd); +} + +static void pseccomp_dbg(const char *ruleset_name, pseccomp_ctx *ctx) +{ + char path[PATH_MAX] = {0}; + + if (getopt_used(OPT_SECCOMP_DEBUG)) { + errno = 0; + if (mkdir(getopt_str(OPT_DEBUG_DIR), S_IRWXU) && errno != EEXIST) + FATAL("Create directory '%s'", getopt_str(OPT_DEBUG_DIR)); + snprintf(path, sizeof path, "%s/seccomp_%s.txt", getopt_str(OPT_DEBUG_DIR), + ruleset_name); + pseccomp_export(path, ctx, 1); + snprintf(path, sizeof path, "%s/seccomp_%s.bin", getopt_str(OPT_DEBUG_DIR), + ruleset_name); + pseccomp_export(path, ctx, 0); + } +} + static int pseccomp_using_valgrind(void) { #ifdef HAVE_VALGRIND @@ -231,6 +271,8 @@ int pseccomp_default_rules(pseccomp_ctx *ctx) default_allowed_syscalls[i], 0); } + pseccomp_dbg("default", ctx); + return seccomp_load(ctx->sfilter); } @@ -245,6 +287,8 @@ int pseccomp_protocol_rules(pseccomp_ctx *ctx) seccomp_rule_add(ctx->sfilter, SCMP_ACT_ERRNO(EINVAL), protocol_disabled_syscalls[i], 0); + pseccomp_dbg("protocol", ctx); + return seccomp_load(ctx->sfilter); } @@ -258,6 +302,11 @@ int pseccomp_jail_rules(pseccomp_ctx *ctx) for (i = 0; i < SIZEOF(jail_allowed_syscalls); ++i) seccomp_rule_add(ctx->sfilter, SCMP_ACT_ALLOW, jail_allowed_syscalls[i], 0); - +#if 0 + /* + * Inactive until we are using pivot_root instead of chroot in src/jail. + */ + pseccomp_dbg("jail", ctx); +#endif return seccomp_load(ctx->sfilter); } |