[lxc-devel] [lxc/master] [RFC, untested] reject lxc.mount.entries which fall outside the container rootfs

hallyn on Github lxc-bot at linuxcontainers.org
Wed Feb 20 16:43:21 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 360 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190220/8a0f1e1d/attachment.bin>
-------------- next part --------------
From f742c6a97bb66721f7376a93ee5f589e592cd677 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <shallyn at cisco.com>
Date: Tue, 19 Feb 2019 14:38:36 -0800
Subject: [PATCH] [RFC] reject lxc.mount.entries which fall outside the
 container rootfs

Closes 2766

Add a lxc.container.conf knob to allow them.
---
 doc/lxc.container.conf.sgml.in | 15 +++++++++++++++
 src/lxc/conf.c                 | 14 +++++++++++++-
 src/lxc/conf.h                 |  1 +
 src/lxc/confile.c              | 30 ++++++++++++++++++++++++++++++
 4 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in
index 00b51a94aa..afda01d97f 100644
--- a/doc/lxc.container.conf.sgml.in
+++ b/doc/lxc.container.conf.sgml.in
@@ -1094,6 +1094,21 @@ dev/null proc/kcore none bind,relative 0 0
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term>
+            <option>lxc.allow_abs_mountentries</option>
+          </term>
+          <listitem>
+            <para>
+              Specify whether a mount target for<option>lxc.mount.entry</option>
+	      may fall outside the container rootfs.  Default is no.
+            </para>
+            <para>
+              Valid values are 0 (false) and 1 (true).
+            </para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term>
             <option>lxc.mount.auto</option>
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index cb5730af65..d792d17ce2 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2331,6 +2331,11 @@ static int mount_entry_on_relative_rootfs(struct mntent *mntent,
 	return mount_entry_on_generic(mntent, path, rootfs, lxc_name, lxc_path);
 }
 
+static bool startswith(const char *string, const char *start)
+{
+	return strncmp(string, start, strlen(start)) == 0;
+}
+
 static int mount_file_entries(const struct lxc_conf *conf,
 			      const struct lxc_rootfs *rootfs, FILE *file,
 			      const char *lxc_name, const char *lxc_path)
@@ -2346,9 +2351,16 @@ static int mount_file_entries(const struct lxc_conf *conf,
 		else if (mntent.mnt_dir[0] != '/')
 			ret = mount_entry_on_relative_rootfs(&mntent, rootfs,
 							     lxc_name, lxc_path);
-		else
+		else {
+			if (!conf->allow_abs_mountentries) {
+				if (!startswith(mntent.mnt_dir, rootfs->path)) {
+					ERROR("Dangerous container mount onto %s", mntent.mnt_dir);
+					return -1;
+				}
+			}
 			ret = mount_entry_on_absolute_rootfs(&mntent, rootfs,
 							     lxc_name, lxc_path);
+		}
 		if (ret < 0)
 			return -1;
 	}
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 85daf1b6a5..1bc95cfeb1 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -264,6 +264,7 @@ struct lxc_conf {
 		char *fstab;
 		int auto_mounts;
 		struct lxc_list mount_list;
+		bool allow_abs_mountentries;
 	};
 
 	struct lxc_list caps;
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index cecb65548e..f62e409fd7 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -115,6 +115,7 @@ lxc_config_define(log_syslog);
 lxc_config_define(monitor);
 lxc_config_define(monitor_signal_pdeath);
 lxc_config_define(mount);
+lxc_config_define(allow_abs_path);
 lxc_config_define(mount_auto);
 lxc_config_define(mount_fstab);
 lxc_config_define(namespace_clone);
@@ -205,6 +206,7 @@ static struct lxc_config_t config_jump_table[] = {
 	{ "lxc.monitor.signal.pdeath",     set_config_monitor_signal_pdeath,       get_config_monitor_signal_pdeath,       clr_config_monitor_signal_pdeath,     },
 	{ "lxc.mount.auto",                set_config_mount_auto,                  get_config_mount_auto,                  clr_config_mount_auto,                },
 	{ "lxc.mount.entry",               set_config_mount,                       get_config_mount,                       clr_config_mount,                     },
+	{ "lxc.allow_abs_mountentries",    set_config_allow_abs_mountentries,      get_config_allow_abs_mountentries,      clr_config_allow_abs_mountentries,          },
 	{ "lxc.mount.fstab",               set_config_mount_fstab,                 get_config_mount_fstab,                 clr_config_mount_fstab,               },
 	{ "lxc.namespace.clone",           set_config_namespace_clone,             get_config_namespace_clone,             clr_config_namespace_clone,           },
 	{ "lxc.namespace.keep",            set_config_namespace_keep,              get_config_namespace_keep,              clr_config_namespace_keep,            },
@@ -1868,6 +1870,20 @@ static int set_config_mount(const char *key, const char *value,
 	return 0;
 }
 
+static int set_config_allow_abs_mountentries(const char *key, const char *value,
+			    struct lxc_conf *lxc_conf, void *data)
+{
+	if (lxc_config_value_empty(value) || value[0] == '0')
+		lxc_conf->allow_auto_mounts = false;
+	else if (value[0] == '1')
+		lxc_conf->allow_auto_mounts = true;
+	else {
+		ERROR("Bad value for allow_abs_mountentries: \"%s\"", value)
+		return 1
+	}
+	return 0
+}
+
 int add_elem_to_mount_list(const char *value, struct lxc_conf *lxc_conf) {
 	return set_config_mount(NULL, value, lxc_conf, NULL);
 }
@@ -3382,6 +3398,13 @@ static int get_config_mount_fstab(const char *key, char *retv, int inlen,
 	return lxc_get_conf_str(retv, inlen, c->fstab);
 }
 
+static int get_config_allow_abs_mountentries(const char *key, char *retv, int inlen,
+				  struct lxc_conf *c, void *data)
+{
+	return lxc_get_conf_bool(c, retv, inlen, c->allow_abs_mountentries);
+}
+
+
 static int get_config_mount_auto(const char *key, char *retv, int inlen,
 				 struct lxc_conf *c, void *data)
 {
@@ -4105,6 +4128,13 @@ static inline int clr_config_mount(const char *key, struct lxc_conf *c,
 	return lxc_clear_mount_entries(c);
 }
 
+static inline int clr_config_allow_abs_mountentries(const char *key, struct lxc_conf *c,
+				   void *data)
+{
+	c->allow_abs_mountentries = false;
+	return 0;
+}
+
 static inline int clr_config_mount_auto(const char *key, struct lxc_conf *c,
 					void *data)
 {


More information about the lxc-devel mailing list