[lxc-devel] [PATCH] bdev: allow unprivileged overlayfs snapshots
Stéphane Graber
stgraber at ubuntu.com
Tue Feb 11 22:26:38 UTC 2014
On Tue, Feb 11, 2014 at 01:43:19PM -0600, Serge Hallyn wrote:
> Also make sure to chown the new rootfs path to the container owner.
> This is how we make sure that the container root is allowed to write
> under delta0.
>
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
Acked-by: Stéphane Graber <stgraber at ubuntu.com>
Some more kernel work remains to be done (as we discussed) but the LXC
side is sane and with those remaining changes done, file removal should
work too :)
> ---
> src/lxc/bdev.c | 55 +++++++++++++++++++++++++++++++++++--------------------
> src/lxc/conf.c | 19 +++++++++++++++++++
> 2 files changed, 54 insertions(+), 20 deletions(-)
>
> diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
> index 01c06e1..7f8ab9c 100644
> --- a/src/lxc/bdev.c
> +++ b/src/lxc/bdev.c
> @@ -2130,6 +2130,31 @@ bool bdev_is_dir(const char *path)
> }
>
> /*
> + * is an unprivileged user allowed to make this kind of snapshot
> + */
> +static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
> + bool maybesnap)
> +{
> + if (!t) {
> + // new type will be same as original
> + // (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, "overlayfs") == 0 ||
> + strcmp(b->type, "loop") == 0)
> + return true;
> + return false;
> + }
> +
> + // 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, "loop") == 0)
> + return true;
> + return false;
> +}
> +
> +/*
> * If we're not snaphotting, then bdev_copy becomes a simple case of mount
> * the original, mount the new, and rsync the contents.
> */
> @@ -2180,26 +2205,6 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
> }
> }
>
> - /* check for privilege */
> - if (am_unpriv()) {
> - if (snap && !maybe_snap) {
> - ERROR("Unprivileged users cannot snapshot");
> - bdev_put(orig);
> - return NULL;
> - }
> - if (bdevtype && strcmp(bdevtype, "dir") != 0) {
> - ERROR("Unprivileged users can only make dir copy-clones");
> - bdev_put(orig);
> - return NULL;
> - }
> - if (strcmp(orig->type, "dir") != 0) {
> - ERROR("Unprivileged users can only make dir copy-clones");
> - bdev_put(orig);
> - return NULL;
> - }
> - }
> -
> -
> /*
> * special case for snapshot - if caller requested maybe_snapshot and
> * keepbdevtype and backing store is directory, then proceed with a copy
> @@ -2214,6 +2219,12 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
> if (!bdevtype && !keepbdevtype && snap && strcmp(orig->type , "dir") == 0)
> bdevtype = "overlayfs";
>
> + if (am_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) {
> + ERROR("Unsupported snapshot type for unprivileged users");
> + bdev_put(orig);
> + return NULL;
> + }
> +
> *needs_rdep = 0;
> if (bdevtype && strcmp(orig->type, "dir") == 0 &&
> strcmp(bdevtype, "overlayfs") == 0)
> @@ -2232,6 +2243,10 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
> bdev_put(new);
> return NULL;
> }
> +
> + if (am_unpriv() && chown_mapped_root(new->src, c0->lxc_conf) < 0)
> + WARN("Failed to update ownership of %s", new->dest);
> +
> if (snap)
> return new;
>
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index 4e25432..522c590 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -3364,6 +3364,7 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
> uid_t rootid;
> pid_t pid;
> unsigned long val;
> + char *chownpath = path;
>
> if (!get_mapped_rootid(conf, ID_TYPE_UID, &val)) {
> ERROR("No mapping for container root");
> @@ -3371,6 +3372,24 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
> }
> rootid = (uid_t) val;
>
> + /*
> + * In case of overlay, we want only the writeable layer
> + * to be chowned
> + */
> + if (strncmp(path, "overlayfs:", 10) == 0) {
> + chownpath = strchr(path, ':');
> + if (!chownpath) {
> + ERROR("Bad overlay path: %s", path);
> + return -1;
> + }
> + chownpath = strchr(chownpath+1, ':');
> + if (!chownpath) {
> + ERROR("Bad overlay path: %s", path);
> + return -1;
> + }
> + chownpath++;
> + }
> + path = chownpath;
> if (geteuid() == 0) {
> if (chown(path, rootid, -1) < 0) {
> ERROR("Error chowning %s", path);
> --
> 1.9.rc1
>
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel
--
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20140211/e30e1037/attachment.pgp>
More information about the lxc-devel
mailing list