Quoting KATOH Yasufumi ([email protected]):
> Hi,
> 
> Current aufs supports FS_USERNS_MOUNT by using module parameter
> 'allow_userns'. So we can start an unprivileged container using
> aufs. (But ubuntu kernel do not support it?)
>   
> https://github.com/sfjro/aufs3-linux/commit/548fa48dbf52ad80e55deb8ca945c4f7814dbf94
> 
> How about support unprivileged aufs container?
> 
> I tried creating the patch. (but I have not done enough test.)
> 
> This moves the place of xino file to /dev/shm, because get_rundir
> always return '/run' when mount aufs, so unpriv container can't
> write. This idea is from
> docker(https://github.com/docker/docker/pull/826).

What if root starts a container, creates root-owned /dev/shm/lxc,
and then unpriv user tries to start a container?

> 
> 
> From 2c489a3887d904f2a4fe771d250fda55947f27d3 Mon Sep 17 00:00:00 2001
> From: KATOH Yasufumi <[email protected]>
> Date: Tue, 21 Apr 2015 19:29:19 +0900
> Subject: [PATCH] aufs: Support unprivileged clone, mount
> 
> Current aufs supports FS_USERNS_MOUNT by using allow_userns module parameter.
> 
> Signed-off-by: KATOH Yasufumi <[email protected]>
> ---
>  src/lxc/bdev.c | 62 
> ++++++++++++++++++++++++++++++++++------------------------
>  1 file changed, 36 insertions(+), 26 deletions(-)
> 
> diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
> index cf7c043..051c34d 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/lxc";
>  
>       if (strcmp(bdev->type, "aufs"))
>               return -22;
> @@ -2583,41 +2583,26 @@ 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) {
> +     if (mkdir_p(xinopath, 0755) < 0) {
>               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/lxc/aufs.xino parameter to mount options
>       //
>       // see 
> http://www.mail-archive.com/[email protected]/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=/aufs.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/aufs.xino", 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=/aufs.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/aufs.xino", upper, lower, xinopath);
>       }
>  
> -     free(rundir);
> -
>       if (ret < 0 || ret >= len) {
>               free(mntdata);
>               return -1;
> @@ -2660,6 +2645,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 +2672,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 +2707,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 +3312,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 +3322,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
> [email protected]
> http://lists.linuxcontainers.org/listinfo/lxc-devel
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to