[lxc-devel] [lxc/master] Add keyring option

blenk92 on Github lxc-bot at linuxcontainers.org
Wed Jan 29 17:30:52 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 1015 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200129/56d92aa6/attachment.bin>
-------------- next part --------------
From 23dfe3b4e55a524d7b1fc17498a1cb14da178e75 Mon Sep 17 00:00:00 2001
From: Maximilian Blenk <Maximilian.Blenk at bmw.de>
Date: Wed, 29 Jan 2020 17:09:50 +0100
Subject: [PATCH 1/2] container.conf: Add option to set keyring SELinux context

lxc set's up a new session keyring for every container by default.
If executed on an SELinux enabled system, by default, the keyring
inherits the label of the creating process. If executed with the
currently available SELinux policy, this means that the keyring
is labeled with the lxc_t type. Applications inside the container,
however, might expect that the keyring is labeled with a certain
context (and will fail to access the keyring if it's not explicitly
allowed in the global policy). This patch introduces the config
option lxc.selinux.keyring_context which enables to specify the
label of the newly created keyring. That is, the keyring can be
labeled with the label expected by the started application.

Signed-off-by: Maximilian Blenk <Maximilian.Blenk at bmw.de>
---
 config/selinux/lxc.te |  3 +++
 src/lxc/conf.c        |  3 ++-
 src/lxc/conf.h        |  1 +
 src/lxc/confile.c     | 23 +++++++++++++++++++++++
 src/lxc/lsm/lsm.c     | 13 +++++++++++++
 src/lxc/lsm/lsm.h     |  2 ++
 src/lxc/lsm/selinux.c | 13 +++++++++++++
 src/lxc/utils.c       |  9 ++++++++-
 src/lxc/utils.h       |  2 +-
 9 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/config/selinux/lxc.te b/config/selinux/lxc.te
index bb4bfe3a8f..d3f78d80b8 100644
--- a/config/selinux/lxc.te
+++ b/config/selinux/lxc.te
@@ -84,5 +84,8 @@ allow lxc_t self:packet_socket create_socket_perms;
 allow lxc_t self:rawip_socket create_socket_perms;
 allow lxc_t self:netlink_route_socket create_netlink_socket_perms;
 
+# Needed to set label that the keyring will be created with
+allow lxc_t self:process { setkeycreate };
+
 dontaudit lxc_t sysctl_kernel_t:file write;
 dontaudit lxc_t sysctl_modprobe_t:file write;
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 457e1e1658..b402953763 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2742,6 +2742,7 @@ struct lxc_conf *lxc_conf_init(void)
 	new->lsm_aa_profile = NULL;
 	lxc_list_init(&new->lsm_aa_raw);
 	new->lsm_se_context = NULL;
+	new->lsm_se_keyring_context = NULL;
 	new->tmp_umount_proc = false;
 	new->tmp_umount_proc = 0;
 	new->shmount.path_host = NULL;
@@ -3548,7 +3549,7 @@ int lxc_setup(struct lxc_handler *handler)
 		}
 	}
 
-	ret = lxc_setup_keyring();
+	ret = lxc_setup_keyring(lxc_conf->lsm_se_keyring_context);
 	if (ret < 0)
 		return -1;
 
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 3917cfc941..d916f94dc0 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -298,6 +298,7 @@ struct lxc_conf {
 	unsigned int lsm_aa_allow_incomplete;
 	struct lxc_list lsm_aa_raw;
 	char *lsm_se_context;
+	char *lsm_se_keyring_context;
 	bool tmp_umount_proc;
 	struct lxc_seccomp seccomp;
 	int maincmd_fd;
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index c27d432d81..1db090b68b 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -136,6 +136,7 @@ lxc_config_define(seccomp_allow_nesting);
 lxc_config_define(seccomp_notify_cookie);
 lxc_config_define(seccomp_notify_proxy);
 lxc_config_define(selinux_context);
+lxc_config_define(selinux_keyring_context);
 lxc_config_define(signal_halt);
 lxc_config_define(signal_reboot);
 lxc_config_define(signal_stop);
@@ -233,6 +234,7 @@ static struct lxc_config_t config_jump_table[] = {
 	{ "lxc.seccomp.notify.proxy",      set_config_seccomp_notify_proxy,        get_config_seccomp_notify_proxy,        clr_config_seccomp_notify_proxy,      },
 	{ "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.selinux.keyring_context",   set_config_selinux_keyring_context,     get_config_selinux_keyring_context,     clr_config_selinux_keyring_context    },
 	{ "lxc.signal.halt",               set_config_signal_halt,                 get_config_signal_halt,                 clr_config_signal_halt,               },
 	{ "lxc.signal.reboot",             set_config_signal_reboot,               get_config_signal_reboot,               clr_config_signal_reboot,             },
 	{ "lxc.signal.stop",               set_config_signal_stop,                 get_config_signal_stop,                 clr_config_signal_stop,               },
@@ -1469,6 +1471,12 @@ static int set_config_selinux_context(const char *key, const char *value,
 	return set_config_string_item(&lxc_conf->lsm_se_context, value);
 }
 
+static int set_config_selinux_keyring_context(const char *key, const char *value,
+					      struct lxc_conf *lxc_conf, void *data)
+{
+	return set_config_string_item(&lxc_conf->lsm_se_keyring_context, value);
+}
+
 static int set_config_log_file(const char *key, const char *value,
 			      struct lxc_conf *c, void *data)
 {
@@ -3539,6 +3547,13 @@ static int get_config_selinux_context(const char *key, char *retv, int inlen,
 	return lxc_get_conf_str(retv, inlen, c->lsm_se_context);
 }
 
+static int get_config_selinux_keyring_context(const char *key, char *retv, int inlen,
+					      struct lxc_conf *c, void *data)
+{
+	return lxc_get_conf_str(retv, inlen, c->lsm_se_keyring_context);
+}
+
+
 /* If you ask for a specific cgroup value, i.e. lxc.cgroup.devices.list, then
  * just the value(s) will be printed. Since there still could be more than one,
  * it is newline-separated.
@@ -4405,6 +4420,14 @@ static inline int clr_config_selinux_context(const char *key,
 	return 0;
 }
 
+static inline int clr_config_selinux_keyring_context(const char *key,
+						     struct lxc_conf *c, void *data)
+{
+	free(c->lsm_se_keyring_context);
+	c->lsm_se_keyring_context = NULL;
+	return 0;
+}
+
 static inline int clr_config_cgroup_controller(const char *key,
 					       struct lxc_conf *c, void *data)
 {
diff --git a/src/lxc/lsm/lsm.c b/src/lxc/lsm/lsm.c
index 2b80914ca0..68ad6ad76f 100644
--- a/src/lxc/lsm/lsm.c
+++ b/src/lxc/lsm/lsm.c
@@ -193,3 +193,16 @@ void lsm_process_cleanup(struct lxc_conf *conf, const char *lxcpath)
 
 	drv->cleanup(conf, lxcpath);
 }
+
+int lsm_keyring_label_set(const char *label) {
+
+	if (!drv) {
+		ERROR("LSM driver not inited");
+		return -1;
+	}
+
+	if (!drv->keyring_label_set)
+		return 0;
+
+	return drv->keyring_label_set(label);
+}
diff --git a/src/lxc/lsm/lsm.h b/src/lxc/lsm/lsm.h
index 7586d20f2b..ad8639dbb2 100644
--- a/src/lxc/lsm/lsm.h
+++ b/src/lxc/lsm/lsm.h
@@ -17,6 +17,7 @@ struct lsm_drv {
 	char *(*process_label_get)(pid_t pid);
 	int (*process_label_set)(const char *label, struct lxc_conf *conf,
 				 bool on_exec);
+        int (*keyring_label_set)(const char* label);
 	int (*prepare)(struct lxc_conf *conf, const char *lxcpath);
 	void (*cleanup)(struct lxc_conf *conf, const char *lxcpath);
 };
@@ -32,5 +33,6 @@ extern int lsm_process_label_fd_get(pid_t pid, bool on_exec);
 extern int lsm_process_label_set_at(int label_fd, const char *label,
 				    bool on_exec);
 extern void lsm_process_cleanup(struct lxc_conf *conf, const char *lxcpath);
+extern int lsm_keyring_label_set(const char *label);
 
 #endif /* __LXC_LSM_H */
diff --git a/src/lxc/lsm/selinux.c b/src/lxc/lsm/selinux.c
index 4e537bb264..fdb2e39cc2 100644
--- a/src/lxc/lsm/selinux.c
+++ b/src/lxc/lsm/selinux.c
@@ -85,11 +85,24 @@ static int selinux_process_label_set(const char *inlabel, struct lxc_conf *conf,
 	return 0;
 }
 
+/*
+ * selinux_keyring_label_set: Set SELinux context that will be assigned to the keyring
+ *
+ * @label   : label string
+ *
+ * Returns 0 on success, < 0 on failure
+ */
+static int selinux_keyring_label_set(const char *label)
+{
+	return setkeycreatecon_raw(label);
+};
+
 static struct lsm_drv selinux_drv = {
 	.name = "SELinux",
 	.enabled           = is_selinux_enabled,
 	.process_label_get = selinux_process_label_get,
 	.process_label_set = selinux_process_label_set,
+	.keyring_label_set = selinux_keyring_label_set,
 };
 
 struct lsm_drv *lsm_selinux_drv_init(void)
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index da2d3112bd..a456f814b7 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -27,6 +27,7 @@
 
 #include "config.h"
 #include "log.h"
+#include "lsm/lsm.h"
 #include "lxclock.h"
 #include "memory_utils.h"
 #include "namespace.h"
@@ -1835,11 +1836,17 @@ int recursive_destroy(const char *dirname)
 	return fret;
 }
 
-int lxc_setup_keyring(void)
+int lxc_setup_keyring(const char *keyring_label)
 {
 	key_serial_t keyring;
 	int ret = 0;
 
+	if (keyring_label) {
+		if (lsm_keyring_label_set(keyring_label) < 0) {
+			ERROR("Couldn't set keyring label");
+		}
+	}
+
 	/* Try to allocate a new session keyring for the container to prevent
 	 * information leaks.
 	 */
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 8b3cfdfa04..110ff3960b 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -232,6 +232,6 @@ extern uint64_t lxc_find_next_power2(uint64_t n);
 extern int lxc_set_death_signal(int signal, pid_t parent, int parent_status_fd);
 extern int fd_cloexec(int fd, bool cloexec);
 extern int recursive_destroy(const char *dirname);
-extern int lxc_setup_keyring(void);
+extern int lxc_setup_keyring(const char *keyring_label);
 
 #endif /* __LXC_UTILS_H */

From 9cb596dd1fa8f42e3811be87f0b98853af86e26f Mon Sep 17 00:00:00 2001
From: Maximilian Blenk <Maximilian.Blenk at bmw.de>
Date: Wed, 29 Jan 2020 18:10:38 +0100
Subject: [PATCH 2/2] doc: Add doc for lxc.selinux.keyring_context option

Signed-off-by: Maximilian Blenk <Maximilian.Blenk at bmw.de>
---
 doc/lxc.container.conf.sgml.in | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in
index 784f833733..01eb45b655 100644
--- a/doc/lxc.container.conf.sgml.in
+++ b/doc/lxc.container.conf.sgml.in
@@ -1931,6 +1931,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
             </para>
             <programlisting>lxc.selinux.context = system_u:system_r:lxc_t:s0:c22</programlisting>
           </listitem>
+          <term>
+            <option>lxc.selinux.keyring_context</option>
+          </term>
+          <listitem>
+            <para>
+              Specify the SELinux context under which the container's keyring
+              should be created. By default this is the context lxc is executed
+              under.
+            </para>
+            <programlisting>lxc.selinux.keyring_context = system_u:system_r:lxc_t:s0:c22</programlisting>
+          </listitem>
         </varlistentry>
       </variablelist>
     </refsect2>


More information about the lxc-devel mailing list