sandbox: add support for SECCOMP_FILTER_FLAG_LOG
authorRobert Swiecki <robert@swiecki.net>
Wed, 23 May 2018 13:32:45 +0000 (15:32 +0200)
committerRobert Swiecki <robert@swiecki.net>
Wed, 23 May 2018 13:32:45 +0000 (15:32 +0200)
cmdline.cc
nsjail.h
sandbox.cc

index 63f123124c2152ba9654359f1f647230ed9e1c88..bd80a727a651a15b38dea7355357d6bade54c65e 100644 (file)
@@ -131,6 +131,7 @@ struct custom_option custom_opts[] = {
     { { "proc_rw", no_argument, NULL, 0x0606 }, "Is procfs mounted as R/W (default: R/O)" },
     { { "seccomp_policy", required_argument, NULL, 'P' }, "Path to file containing seccomp-bpf policy (see kafel/)" },
     { { "seccomp_string", required_argument, NULL, 0x0901 }, "String with kafel seccomp-bpf policy (see kafel/)" },
+    { { "seccomp_log", no_argument, NULL, 0x0902 }, "Use SECCOMP_FILTER_FLAG_LOG. Log all actions except SECCOMP_RET_ALLOW)" },
     { { "cgroup_mem_max", required_argument, NULL, 0x0801 }, "Maximum number of bytes to use in the group (default: '0' - disabled)" },
     { { "cgroup_mem_mount", required_argument, NULL, 0x0802 }, "Location of memory cgroup FS (default: '/sys/fs/cgroup/memory')" },
     { { "cgroup_mem_parent", required_argument, NULL, 0x0803 }, "Which pre-existing memory cgroup to use as a parent (default: 'NSJAIL')" },
@@ -449,6 +450,7 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
        nsjconf->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
        nsjconf->seccomp_fprog.filter = NULL;
        nsjconf->seccomp_fprog.len = 0;
+        nsjconf->seccomp_log = false;
 
        nsjconf->openfds.push_back(STDIN_FILENO);
        nsjconf->openfds.push_back(STDOUT_FILENO);
@@ -818,6 +820,9 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
                case 0x901:
                        nsjconf->kafel_string = optarg;
                        break;
+               case 0x902:
+                       nsjconf->seccomp_log = true;
+                       break;
                default:
                        cmdlineUsage(argv[0]);
                        return nullptr;
index 07b2696f86f1d9778dc177d71a28084b9081cfd8..7cccd689f6802f82430b479d17c0a4cb28a53046 100644 (file)
--- a/nsjail.h
+++ b/nsjail.h
@@ -143,6 +143,7 @@ struct nsjconf_t {
        std::string kafel_file_path;
        std::string kafel_string;
        struct sock_fprog seccomp_fprog;
+       bool seccomp_log;
        long num_cpus;
        uid_t orig_uid;
        std::vector<mount_t> mountpts;
index 23cd43ada373c22c3c8f9001d7f5621c35090f26..f1fd5eb81b74f07e7493edbb776ed96ec6e580d9 100644 (file)
@@ -26,6 +26,8 @@
 #include <stddef.h>
 #include <stdlib.h>
 #include <sys/prctl.h>
+#include <sys/syscall.h>
+#include <unistd.h>
 
 extern "C" {
 #include "kafel.h"
@@ -38,6 +40,14 @@ namespace sandbox {
 #define PR_SET_NO_NEW_PRIVS 38
 #endif /* PR_SET_NO_NEW_PRIVS */
 
+#ifndef SECCOMP_FILTER_FLAG_TSYNC
+#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0)
+#endif /* SECCOMP_FILTER_FLAG_TSYNC */
+
+#ifndef SECCOMP_FILTER_FLAG_LOG
+#define SECCOMP_FILTER_FLAG_LOG (1UL << 1)
+#endif /* SECCOMP_FILTER_FLAG_LOG */
+
 static bool prepareAndCommit(nsjconf_t* nsjconf) {
        if (nsjconf->kafel_file_path.empty() && nsjconf->kafel_string.empty()) {
                return true;
@@ -47,7 +57,26 @@ static bool prepareAndCommit(nsjconf_t* nsjconf) {
                PLOG_W("prctl(PR_SET_NO_NEW_PRIVS, 1) failed");
                return false;
        }
-       if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &nsjconf->seccomp_fprog, 0, 0)) {
+       if (nsjconf->seccomp_log) {
+#ifndef __NR_seccomp
+               LOG_E(
+                   "The __NR_seccomp is not defined with this kernel header files (kernel headers "
+                   "too old?)");
+               return false;
+#else
+               if (syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER,
+                       SECCOMP_FILTER_FLAG_TSYNC | SECCOMP_FILTER_FLAG_LOG,
+                       &nsjconf->seccomp_fprog) == -1) {
+                       PLOG_E(
+                           "seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC | "
+                           "SECCOMP_FILTER_FLAG_LOG) failed");
+                       return false;
+               }
+               return true;
+#endif /* __NR_seccomp */
+       }
+
+       if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &nsjconf->seccomp_fprog, 0UL, 0UL)) {
                PLOG_W("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER) failed");
                return false;
        }