aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2018-08-30 23:51:59 +0200
committerToni Uhlig <matzeton@googlemail.com>2018-08-30 23:51:59 +0200
commitd9f5862f0c29de47940785c84109fab9fa69dbb5 (patch)
tree4775e50e6b2814540888ed1059e04dba5af97840
parent6cd6fc810c759b17ab1d8eff648d22b38f1df230 (diff)
enable SECCOMP text/bpf export
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r--configure.ac7
-rw-r--r--src/options.c4
-rw-r--r--src/options.h2
-rw-r--r--src/pseccomp.c51
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);
}