[lxc-devel] [PATCH] aufs: Support unprivileged clone, mount

KATOH Yasufumi karma at jazz.email.ne.jp
Thu May 7 09:26:57 UTC 2015


>>> On Thu, 30 Apr 2015 14:02:55 +0000
    in message   "Re: [lxc-devel] [PATCH] aufs: Support unprivileged clone, mount"
                  Serge Hallyn-san wrote:

> Quoting KATOH Yasufumi (karma at jazz.email.ne.jp):
> > Current aufs supports FS_USERNS_MOUNT by using allow_userns module
> > parameter. It allows root in userns to mount aufs.
> > 
> > This patch allows an unprivileged container to use aufs.
> > 
> > Signed-off-by: KATOH Yasufumi <karma at jazz.email.ne.jp>
> > ---
> >  src/lxc/bdev.c | 65 +++++++++++++++++++++++++++++++---------------------------
> >  1 file changed, 35 insertions(+), 30 deletions(-)
> > 
> > diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
> > index cf7c043..eb516c8 100644
> > --- a/src/lxc/bdev.c
> > +++ b/src/lxc/bdev.c
> > @@ -2552,12 +2552,12 @@ static int aufs_detect(const char *path)
> >  //
> >  static int aufs_mount(struct bdev *bdev)
> >  {
> > -	char *options, *dup, *lower, *upper, *rundir;
> > +	char *options, *dup, *lower, *upper;
> >  	int len;
> >  	unsigned long mntflags;
> >  	char *mntdata;
> > -	char *runpath;
> >  	int ret;
> > +	const char *xinopath = "/dev/shm/aufs.xino";

> So who will create this directory?  What are its permissions?
> Does aufs somehow autocreate that in such a way that anyone
> can create files (and immediately delete) files there?

Thanks for your reply.

'/dev/shm' may not always exists, or may not always be 1777, so this
code may cause a problem on such a system.

But many software expect the existent of /dev/shm for shared memory
area. So many distributions have /dev/shm. And it is usually mounted
as tmpfs, and its permission is usually set 1777. For example,

  - systemd creates /dev/shm, and mount as tmpfs, and set mode=1777 at
    boot time.
  - Ubuntu Trusty, Debian wheezy has /dev/shm as the link to /run/shm
    (mode=1777)

xino file is created per aufs branch automatically. We can specify the
same xino to multiple aufs mounts. After a aufs priv container is
started, I could run a unpriv aufs container at the same time.

So I think that it is not a problem in many cases.

Does that answer your question?

> >  
> >  	if (strcmp(bdev->type, "aufs"))
> >  		return -22;
> > @@ -2583,41 +2583,21 @@ static int aufs_mount(struct bdev *bdev)
> >  	// TODO We should check whether bdev->src is a blockdev, and if so
> >  	// but for now, only support aufs of a basic directory
> >  
> > -	rundir = get_rundir();
> > -	if (!rundir)
> > -		return -1;
> > -
> > -	len = strlen(rundir) + strlen("/lxc") + 1;
> > -	runpath = alloca(len);
> > -	ret = snprintf(runpath, len, "%s/lxc", rundir);
> > -	if (ret < 0 || ret >= len) {
> > -		free(mntdata);
> > -		free(rundir);
> > -		return -1;
> > -	}
> > -	if (mkdir_p(runpath, 0755) < 0) {
> > -		free(mntdata);
> > -		free(rundir);
> > -		return -1;
> > -	}
> > -
> >  	// AUFS does not work on top of certain filesystems like (XFS or Btrfs)
> > -	// so add xino=RUNDIR/lxc/aufs.xino parameter to mount options
> > +	// so add xino=/dev/shm/aufs.xino parameter to mount options
> >  	//
> >  	// see http://www.mail-archive.com/aufs-users@lists.sourceforge.net/msg02587.html
> >  	if (mntdata) {
> > -		len = strlen(lower) + strlen(upper) + strlen(runpath) + strlen("br==rw:=ro,,xino=/aufs.xino") + strlen(mntdata) + 1;
> > +		len = strlen(lower) + strlen(upper) + strlen(xinopath) + strlen("br==rw:=ro,,xino=") + strlen(mntdata) + 1;
> >  		options = alloca(len);
> > -		ret = snprintf(options, len, "br=%s=rw:%s=ro,%s,xino=%s/aufs.xino", upper, lower, mntdata, runpath);
> > +		ret = snprintf(options, len, "br=%s=rw:%s=ro,%s,xino=%s", upper, lower, mntdata, xinopath);
> >  	}
> >  	else {
> > -		len = strlen(lower) + strlen(upper) + strlen(runpath) + strlen("br==rw:=ro,xino=/aufs.xino") + 1;
> > +		len = strlen(lower) + strlen(upper) + strlen(xinopath) + strlen("br==rw:=ro,xino=") + 1;
> >  		options = alloca(len);
> > -		ret = snprintf(options, len, "br=%s=rw:%s=ro,xino=%s/aufs.xino", upper, lower, runpath);
> > +		ret = snprintf(options, len, "br=%s=rw:%s=ro,xino=%s", upper, lower, xinopath);
> >  	}
> >  
> > -	free(rundir);
> > -
> >  	if (ret < 0 || ret >= len) {
> >  		free(mntdata);
> >  		return -1;
> > @@ -2660,6 +2640,9 @@ static int aufs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldn
> >  	if (mkdir_p(new->dest, 0755) < 0)
> >  		return -1;
> >  
> > +	if (am_unpriv() && chown_mapped_root(new->dest, conf) < 0)
> > +		WARN("Failed to update ownership of %s", new->dest);
> > +
> >  	if (strcmp(orig->type, "dir") == 0) {
> >  		char *delta, *lastslash;
> >  		int ret, len, lastslashidx;
> > @@ -2684,6 +2667,8 @@ static int aufs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldn
> >  			free(delta);
> >  			return -1;
> >  		}
> > +		if (am_unpriv() && chown_mapped_root(delta, conf) < 0)
> > +			WARN("Failed to update ownership of %s", delta);
> >  
> >  		// the src will be 'aufs:lowerdir:upperdir'
> >  		len = strlen(delta) + strlen(orig->src) + 12;
> > @@ -2717,7 +2702,23 @@ static int aufs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldn
> >  			free(osrc);
> >  			return -ENOMEM;
> >  		}
> > -		if (do_rsync(odelta, ndelta) < 0) {
> > +		if ((ret = mkdir(ndelta, 0755)) < 0 && errno != EEXIST) {
> > +			SYSERROR("error: mkdir %s", ndelta);
> > +			free(osrc);
> > +			free(ndelta);
> > +			return -1;
> > +		}
> > +		if (am_unpriv() && chown_mapped_root(ndelta, conf) < 0)
> > +			WARN("Failed to update ownership of %s", ndelta);
> > +
> > +		struct rsync_data_char rdata;
> > +		rdata.src = odelta;
> > +		rdata.dest = ndelta;
> > +		if (am_unpriv())
> > +			ret = userns_exec_1(conf, rsync_delta_wrapper, &rdata);
> > +		else
> > +			ret = rsync_delta(&rdata);
> > +		if (ret) {
> >  			free(osrc);
> >  			free(ndelta);
> >  			ERROR("copying aufs delta");
> > @@ -3306,6 +3307,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
> >  		// (unless snap && b->type == dir, in which case it will be
> >  		// overlayfs -- which is also allowed)
> >  		if (strcmp(b->type, "dir") == 0 ||
> > +				strcmp(b->type, "aufs") == 0 ||
> >  				strcmp(b->type, "overlayfs") == 0 ||
> >  				strcmp(b->type, "btrfs") == 0 ||
> >  				strcmp(b->type, "loop") == 0)
> > @@ -3315,8 +3317,11 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
> >  
> >  	// unprivileged users can copy and snapshot dir, overlayfs,
> >  	// and loop.  In particular, not zfs, btrfs, or lvm.
> > -	if (strcmp(t, "dir") == 0 || strcmp(t, "overlayfs") == 0 ||
> > -			strcmp(t, "btrfs") == 0 || strcmp(t, "loop") == 0)
> > +	if (strcmp(t, "dir") == 0 ||
> > +		strcmp(t, "aufs") == 0 ||
> > +		strcmp(t, "overlayfs") == 0 ||
> > +		strcmp(t, "btrfs") == 0 ||
> > +		strcmp(t, "loop") == 0)
> >  		return true;
> >  	return false;
> >  }
> > -- 
> > 2.2.1
> > 
> > _______________________________________________
> > lxc-devel mailing list
> > lxc-devel at lists.linuxcontainers.org
> > http://lists.linuxcontainers.org/listinfo/lxc-devel
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel


More information about the lxc-devel mailing list