[lxc-devel] [PATCH v3 6/6] lxc-attach: Add -R option to remount /sys and /proc when only partially attaching

Serge Hallyn serge.hallyn at canonical.com
Thu May 24 14:28:55 UTC 2012


Quoting Christian Seiler (christian at iwakd.de):
> When attaching to only some namespaces of the container but not the mount
> namespace, the contents of /sys and /proc of the host system do not properly
> reflect the context of the container's pid and/or network namespaces, and
> possibly others.
> 
> The introduced -R option adds the possibility to additionally unshare the
> mount namespace (when it is not being attached) and remount /sys and /proc
> in order for those filesystems to properly reflect the container's context
> even when only attaching to some of the namespaces.
> 
> Signed-off-by: Christian Seiler <christian at iwakd.de>
> Acked-by: Serge Hallyn <serge.hallyn at canonical.com>

Note there is no reason to resend this patch for this, but do you think
it would be worthwhile to warn if the user specified -R, but CLONE_NEWNS
was already in the mount flags?

> Cc: Daniel Lezcano <daniel.lezcano at free.fr>
> ---
>  doc/lxc-attach.sgml.in |   44 +++++++++++++++++++++++++++++++++++---------
>  src/lxc/attach.c       |   44 ++++++++++++++++++++++++++++++++++++++++++++
>  src/lxc/attach.h       |    1 +
>  src/lxc/lxc_attach.c   |   22 +++++++++++++++++++++-
>  4 files changed, 101 insertions(+), 10 deletions(-)
> 
> diff --git a/doc/lxc-attach.sgml.in b/doc/lxc-attach.sgml.in
> index 035cd27..1724393 100644
> --- a/doc/lxc-attach.sgml.in
> +++ b/doc/lxc-attach.sgml.in
> @@ -50,7 +50,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
>      <cmdsynopsis><command>lxc-attach <replaceable>-n
>      name</replaceable> <optional>-a
>      arch</optional> <optional>-e</optional> <optional>-s
> -    namespaces</optional>
> +    namespaces</optional> <optional>-R</optional>
>      <optional>-- command</optional></command></cmdsynopsis>
>    </refsynopsisdiv>
>  
> @@ -146,7 +146,30 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
>  	</listitem>
>        </varlistentry>
>  
> -    </variablelist>
> +      <varlistentry>
> +	<term>
> +	  <option>-R, --remount-sys-proc</option>
> +	</term>
> +	<listitem>
> +	  <para>
> +	    When using <option>-s</option> and the mount namespace is not
> +	    included, this flag will cause <command>lxc-attach</command>
> +	    to remount <replaceable>/proc</replaceable> and
> +	    <replaceable>/sys</replaceable> to reflect the current other
> +	    namespace contexts.
> +	  </para>
> +	  <para>
> +	    Please see the <emphasis>Notes</emphasis> section for more
> +	    details.
> +	  </para>
> +	  <para>
> +	    This option will be ignored if one tries to attach to the
> +	    mount namespace anyway.
> +	  </para>
> +	</listitem>
> +      </varlistentry>
> +
> +     </variablelist>
>  
>    </refsect1>
>  
> @@ -229,13 +252,16 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
>        the network namespace.
>      </para>
>      <para>
> -      A workaround is to use <command>lxc-unshare</command> to unshare
> -      the mount namespace after using <command>lxc-attach</command> with
> -      <replaceable>-s PID</replaceable> and/or <replaceable>-s
> -      NETWORK</replaceable> and then unmount and then mount again both
> -      pseudo-filesystems within that new mount namespace, before
> -      executing a program/script that relies on this information to be
> -      correct.
> +      To work around this problem, the <option>-R</option> flag provides
> +      the option to remount <replaceable>/proc</replaceable> and
> +      <replaceable>/sys</replaceable> in order for them to reflect the
> +      network/pid namespace context of the attached process. In order
> +      not to interfere with the host's actual filesystem, the mount
> +      namespace will be unshared (like <command>lxc-unshare</command>
> +      does) before this is done, esentially giving the process a new
> +      mount namespace, which is identical to the hosts's mount namespace
> +      except for the <replaceable>/proc</replaceable> and
> +      <replaceable>/sys</replaceable> filesystems.
>      </para>
>    </refsect1>
>  
> diff --git a/src/lxc/attach.c b/src/lxc/attach.c
> index 37e667f..ec0e083 100644
> --- a/src/lxc/attach.c
> +++ b/src/lxc/attach.c
> @@ -30,6 +30,7 @@
>  #include <fcntl.h>
>  #include <sys/param.h>
>  #include <sys/prctl.h>
> +#include <sys/mount.h>
>  #include <linux/unistd.h>
>  
>  #if !HAVE_DECL_PR_CAPBSET_DROP
> @@ -188,6 +189,49 @@ int lxc_attach_to_ns(pid_t pid, int which)
>  	return 0;
>  }
>  
> +int lxc_attach_remount_sys_proc()
> +{
> +	int ret;
> +
> +	ret = unshare(CLONE_NEWNS);
> +	if (ret < 0) {
> +		SYSERROR("failed to unshare mount namespace");
> +		return -1;
> +	}
> +
> +	/* assume /proc is always mounted, so remount it */
> +	ret = umount2("/proc", MNT_DETACH);
> +	if (ret < 0) {
> +		SYSERROR("failed to unmount /proc");
> +		return -1;
> +	}
> +
> +	ret = mount("none", "/proc", "proc", 0, NULL);
> +	if (ret < 0) {
> +		SYSERROR("failed to remount /proc");
> +		return -1;
> +	}
> +
> +	/* try to umount /sys - if it's not a mount point,
> +	 * we'll get EINVAL, then we ignore it because it
> +	 * may not have been mounted in the first place
> +	 */
> +	ret = umount2("/sys", MNT_DETACH);
> +	if (ret < 0 && errno != EINVAL) {
> +		SYSERROR("failed to unmount /sys");
> +		return -1;
> +	} else if (ret == 0) {
> +		/* remount it */
> +		ret = mount("none", "/sys", "sysfs", 0, NULL);
> +		if (ret < 0) {
> +			SYSERROR("failed to remount /sys");
> +			return -1;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx)
>  {
>  	int last_cap = lxc_caps_last_cap();
> diff --git a/src/lxc/attach.h b/src/lxc/attach.h
> index d96fdae..aab47e3 100644
> --- a/src/lxc/attach.h
> +++ b/src/lxc/attach.h
> @@ -34,6 +34,7 @@ struct lxc_proc_context_info {
>  extern struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid);
>  
>  extern int lxc_attach_to_ns(pid_t other_pid, int which);
> +extern int lxc_attach_remount_sys_proc();
>  extern int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx);
>  
>  #endif
> diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
> index 4f22752..e292bc4 100644
> --- a/src/lxc/lxc_attach.c
> +++ b/src/lxc/lxc_attach.c
> @@ -48,12 +48,14 @@ static const struct option my_longopts[] = {
>  	{"elevated-privileges", no_argument, 0, 'e'},
>  	{"arch", required_argument, 0, 'a'},
>  	{"namespaces", required_argument, 0, 's'},
> +	{"remount-sys-proc", no_argument, 0, 'R'},
>  	LXC_COMMON_OPTIONS
>  };
>  
>  static int elevated_privileges = 0;
>  static signed long new_personality = -1;
>  static int namespace_flags = -1;
> +static int remount_sys_proc = 0;
>  
>  static int my_parser(struct lxc_arguments* args, int c, char* arg)
>  {
> @@ -61,6 +63,7 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg)
>  
>  	switch (c) {
>  	case 'e': elevated_privileges = 1; break;
> +	case 'R': remount_sys_proc = 1; break;
>  	case 'a':
>  		new_personality = lxc_config_parse_arch(arg);
>  		if (new_personality < 0) {
> @@ -102,7 +105,12 @@ Options :\n\
>                      but just to the following OR'd list of flags:\n\
>                      MOUNT, PID, UTSNAME, IPC, USER or NETWORK\n\
>                      WARNING: Using -s implies -e, it may therefore\n\
> -                    leak privileges into the container. Use with care.\n",
> +                    leak privileges into the container. Use with care.\n\
> +  -R, --remount-sys-proc\n\
> +                    Remount /sys and /proc if not attaching to the\n\
> +                    mount namespace when using -s in order to properly\n\
> +                    reflect the correct namespace context. See the\n\
> +                    lxc-attach(1) manual page for details.\n",
>  	.options  = my_longopts,
>  	.parser   = my_parser,
>  	.checker  = NULL,
> @@ -253,6 +261,18 @@ int main(int argc, char *argv[])
>  		lxc_sync_fini_parent(handler);
>  		lxc_cgroup_dispose_attach(cgroup_data);
>  
> +		/* A description of the purpose of this functionality is
> +		 * provided in the lxc-attach(1) manual page. We have to
> +		 * remount here and not in the parent process, otherwise
> +		 * /proc may not properly reflect the new pid namespace.
> +		 */
> +		if (!(namespace_flags & CLONE_NEWNS) && remount_sys_proc) {
> +			ret = lxc_attach_remount_sys_proc();
> +			if (ret < 0) {
> +				return -1;
> +			}
> +		}
> +
>  		if (new_personality < 0)
>  			new_personality = init_ctx->personality;
>  
> -- 
> 1.7.2.5
> 
> 
> ------------------------------------------------------------------------------
> Live Security Virtual Conference
> Exclusive live event will cover all the ways today's security and 
> threat landscape has changed and how IT managers can respond. Discussions 
> will include endpoint security, mobile security and the latest in malware 
> threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel




More information about the lxc-devel mailing list