From 50d86993a7d6bf913372e0514fc491ea49ebdc5c Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Mon, 7 Jan 2019 15:10:52 +0100 Subject: [PATCH] confile: add lxc.seccomp.allow_nesting 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 Signed-off-by: Christian Brauner --- doc/lxc.container.conf.sgml.in | 13 +++++++++++++ src/lxc/api_extensions.h | 1 + src/lxc/conf.h | 1 + src/lxc/confile.c | 30 ++++++++++++++++++++++++++++++ src/lxc/seccomp.c | 9 ++++++--- 5 files changed, 51 insertions(+), 3 deletions(-) diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in index 3db43fa9a..00b51a94a 100644 --- a/doc/lxc.container.conf.sgml.in +++ b/doc/lxc.container.conf.sgml.in @@ -1823,6 +1823,19 @@ dev/null proc/kcore none bind,relative 0 0 + + + + + + + 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. + + + diff --git a/src/lxc/api_extensions.h b/src/lxc/api_extensions.h index 810d39828..3ab5efa3b 100644 --- a/src/lxc/api_extensions.h +++ b/src/lxc/api_extensions.h @@ -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); diff --git a/src/lxc/conf.h b/src/lxc/conf.h index f40807e9a..a9e238ac1 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -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 diff --git a/src/lxc/confile.c b/src/lxc/confile.c index c022cd3de..564cbe38a 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -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) { diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c index 1e14be17e..f90602e1f 100644 --- a/src/lxc/seccomp.c +++ b/src/lxc/seccomp.c @@ -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 -- 2.47.2