]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
confile: add lxc.seccomp.allow_nesting 2771/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Mon, 7 Jan 2019 14:10:52 +0000 (15:10 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Mon, 7 Jan 2019 14:34:08 +0000 (15:34 +0100)
This adds the lxc.seccomp.allow_nesting api extension. If
lxc.seccomp.allow_nesting is set to 1 then seccomp profiles will be
stacked. This way nested containers can load their own seccomp policy on
top of the policy that the outer container might have applied.

Cc: Simon Fels <simon.fels@canonical.com>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
doc/lxc.container.conf.sgml.in
src/lxc/api_extensions.h
src/lxc/conf.h
src/lxc/confile.c
src/lxc/seccomp.c

index 3db43fa9ab87e9173ecbfac4e10976aeff607f21..00b51a94aa9c92d502d2840c711b4a7472465949 100644 (file)
@@ -1823,6 +1823,19 @@ dev/null proc/kcore none bind,relative 0 0
              </para>
           </listitem>
         </varlistentry>
+        <varlistentry>
+          <term>
+            <option>lxc.seccomp.allow_nesting</option>
+          </term>
+          <listitem>
+            <para>
+             If this flag is set to 1, then seccomp filters will be stacked
+             regardless of whether a seccomp profile is already loaded.
+             This allows nested containers to load their own seccomp profile.
+             The default setting is 0.
+             </para>
+          </listitem>
+        </varlistentry>
       </variablelist>
     </refsect2>
 
index 810d39828530d6b52eae6b317b37b97870718be7..3ab5efa3b8ef715bc82a8ea4086b11be98dd6f40 100644 (file)
@@ -41,6 +41,7 @@ static char *api_extensions[] = {
        "mount_injection",
        "cgroup_relative",
        "mount_injection_file",
+       "seccomp_allow_nesting",
 };
 
 static size_t nr_api_extensions = sizeof(api_extensions) / sizeof(*api_extensions);
index f40807e9a31612f255501a71eff0d6773212e92d..a9e238ac160db53ec3e8215df1b7f7fdb6b760fe 100644 (file)
@@ -296,6 +296,7 @@ struct lxc_conf {
        char *lsm_se_context;
        bool tmp_umount_proc;
        char *seccomp;  /* filename with the seccomp rules */
+       unsigned int seccomp_allow_nesting;
 #if HAVE_SCMP_FILTER_CTX
        scmp_filter_ctx seccomp_ctx;
 #endif
index c022cd3dede36ec141a3d1183396c916785c2ea1..564cbe38a0838ee3abaa8edc9c6f087d61d91b01 100644 (file)
@@ -145,6 +145,7 @@ lxc_config_define(rootfs_mount);
 lxc_config_define(rootfs_options);
 lxc_config_define(rootfs_path);
 lxc_config_define(seccomp_profile);
+lxc_config_define(seccomp_allow_nesting);
 lxc_config_define(selinux_context);
 lxc_config_define(signal_halt);
 lxc_config_define(signal_reboot);
@@ -231,6 +232,7 @@ static struct lxc_config_t config_jump_table[] = {
        { "lxc.rootfs.mount",              set_config_rootfs_mount,                get_config_rootfs_mount,                clr_config_rootfs_mount,              },
        { "lxc.rootfs.options",            set_config_rootfs_options,              get_config_rootfs_options,              clr_config_rootfs_options,            },
        { "lxc.rootfs.path",               set_config_rootfs_path,                 get_config_rootfs_path,                 clr_config_rootfs_path,               },
+       { "lxc.seccomp.allow_nesting",     set_config_seccomp_allow_nesting,       get_config_seccomp_allow_nesting,       clr_config_seccomp_allow_nesting,     },
        { "lxc.seccomp.profile",           set_config_seccomp_profile,             get_config_seccomp_profile,             clr_config_seccomp_profile,           },
        { "lxc.selinux.context",           set_config_selinux_context,             get_config_selinux_context,             clr_config_selinux_context,           },
        { "lxc.signal.halt",               set_config_signal_halt,                 get_config_signal_halt,                 clr_config_signal_halt,               },
@@ -771,6 +773,21 @@ static int add_hook(struct lxc_conf *lxc_conf, int which, char *hook)
        return 0;
 }
 
+static int set_config_seccomp_allow_nesting(const char *key, const char *value,
+                                           struct lxc_conf *lxc_conf, void *data)
+{
+       if (lxc_config_value_empty(value))
+               return clr_config_seccomp_allow_nesting(key, lxc_conf, NULL);
+
+       if (lxc_safe_uint(value, &lxc_conf->seccomp_allow_nesting) < 0)
+               return -1;
+
+       if (lxc_conf->seccomp_allow_nesting > 1)
+               return -1;
+
+       return 0;
+}
+
 static int set_config_seccomp_profile(const char *key, const char *value,
                                      struct lxc_conf *lxc_conf, void *data)
 {
@@ -3621,6 +3638,12 @@ static int get_config_console_size(const char *key, char *retv, int inlen,
        return lxc_get_conf_uint64(c, retv, inlen, c->console.log_size);
 }
 
+static int get_config_seccomp_allow_nesting(const char *key, char *retv,
+                                           int inlen, struct lxc_conf *c,
+                                           void *data)
+{
+       return lxc_get_conf_int(c, retv, inlen, c->seccomp_allow_nesting);
+}
 
 static int get_config_seccomp_profile(const char *key, char *retv, int inlen,
                                      struct lxc_conf *c, void *data)
@@ -4205,6 +4228,13 @@ static inline int clr_config_console_size(const char *key, struct lxc_conf *c,
        return 0;
 }
 
+static inline int clr_config_seccomp_allow_nesting(const char *key,
+                                                  struct lxc_conf *c, void *data)
+{
+       c->seccomp_allow_nesting = 0;
+       return 0;
+}
+
 static inline int clr_config_seccomp_profile(const char *key,
                                             struct lxc_conf *c, void *data)
 {
index 1e14be17e95fd9b930c9f3967c4c7849a63ad390..f90602e1f9a32154b19b3d2ebb5d0aae25ae30d7 100644 (file)
@@ -1096,7 +1096,7 @@ bad_line:
  *   1. seccomp is not enabled in the kernel
  *   2. a seccomp policy is already enabled for this task
  */
-static bool use_seccomp(void)
+static bool use_seccomp(const struct lxc_conf *conf)
 {
        int ret, v;
        FILE *f;
@@ -1104,6 +1104,9 @@ static bool use_seccomp(void)
        char *line = NULL;
        bool already_enabled = false, found = false;
 
+       if (conf->seccomp_allow_nesting > 0)
+               return true;
+
        f = fopen("/proc/self/status", "r");
        if (!f)
                return true;
@@ -1143,7 +1146,7 @@ int lxc_read_seccomp_config(struct lxc_conf *conf)
        if (!conf->seccomp)
                return 0;
 
-       if (!use_seccomp())
+       if (!use_seccomp(conf))
                return 0;
 
 #if HAVE_SCMP_FILTER_CTX
@@ -1198,7 +1201,7 @@ int lxc_seccomp_load(struct lxc_conf *conf)
        if (!conf->seccomp)
                return 0;
 
-       if (!use_seccomp())
+       if (!use_seccomp(conf))
                return 0;
 
 #if HAVE_SCMP_FILTER_CTX