[lxc-devel] [PATCH] aufs: support multiple lower layers
Christian Brauner
christianvanbrauner at gmail.com
Tue Jan 26 20:10:37 UTC 2016
On Tue, Jan 26, 2016 at 09:07:17PM +0100, Christian Brauner wrote:
> On Tue, Jan 26, 2016 at 06:51:04PM +0000, Serge Hallyn wrote:
> > Quoting Christian Brauner (christianvanbrauner at gmail.com):
> > > Do it in a safe way by using strstr() to check for the substring ":/" should
> > > ':' be part of a pathname.
> > >
> > > Signed-off-by: Christian Brauner <christian.brauner at mailbox.org>
> >
> > Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>
> >
> > > ---
> > > src/lxc/bdev/lxcaufs.c | 14 ++++++++++----
> > > 1 file changed, 10 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/src/lxc/bdev/lxcaufs.c b/src/lxc/bdev/lxcaufs.c
> > > index a5c34aa..408f6a3 100644
> > > --- a/src/lxc/bdev/lxcaufs.c
> > > +++ b/src/lxc/bdev/lxcaufs.c
> > > @@ -234,7 +234,7 @@ int aufs_detect(const char *path)
> > >
> > > int aufs_mount(struct bdev *bdev)
> > > {
> > > - char *options, *dup, *lower, *upper;
> > > + char *tmp, *options, *dup, *lower, *upper;
> > > int len;
> > > unsigned long mntflags;
> > > char *mntdata;
> > > @@ -250,9 +250,15 @@ int aufs_mount(struct bdev *bdev)
> > > // mount -t aufs -obr=${upper}=rw:${lower}=ro lower dest
> > > dup = alloca(strlen(bdev->src)+1);
> > > strcpy(dup, bdev->src);
> > > - if (!(lower = strchr(dup, ':')))
> > > - return -22;
> > > - if (!(upper = strchr(++lower, ':')))
> > > + /* support multiple lower layers */
> > > + if (!(lower = strstr(dup, ":/")))
> > > + return -22;
> > > + lower++;
> > > + upper = lower;
> > > + while ((tmp = strstr(++upper, ":/"))) {
> > > + upper = tmp;
> > > + }
> > > + if (--upper == lower)
> > > return -22;
> >
> > Hm, so if lower = /some/path:/other/path, strstr will result in upper =
> > ':', then you check --upper and up with upper pointing to the last 'h'
> > in /some/path. Then you set that to \0. I'm probably off since this
> > would've failed for you immediately, but why am I wrong?
> Hm, here is how I understood it:
>
> **Case A: "Everything as expected"**
>
> lxc.rootfs = aufs:/lower1:/lower2:/upper
>
> if (!(lower = strchr(dup, ':')))
> return -22;
Typo: It should be (and is correct in the patch):
if (!(lower = strstr(dup, ":/")))
return -22;
>
> now we have
>
> // lower = :/lower1:/lower2:/upper
>
> we do
>
> lower++;
>
> to move forward and not have strstr() do the work from the beginning again.
>
> Now we have
>
> // lower = /lower1:/lower2:/upper
>
> we set
>
> upper = lower;
>
> and have
>
> // upper = lower = /lower1:/lower2:/upper
>
> we do
>
> while ((tmp = strstr(++upper, ":/"))) {
> upper = tmp;
> }
>
> and end up with:
>
> // upper = /upper
>
> now we do
>
> if (--upper == lower)
> return -22;
>
> and as you correctly noticed we compare
>
> // :/upper
>
> with
> // /lower1:/lower2
>
> But that is by design: For a case where we find at least two path entries this
> test really does not serve any purpose at all. Moving back or forth one byte
> does not alter the fact that we found two different entries. It becomes import
> for a case where we fail to find a second path entry.
>
> Now we set:
>
> *upper = '\0';
>
> which is at
>
> // :/upper
>
> and hence "split" the rootfs string
>
> // aufs:/lower1:/lower2:/upper
>
> into
>
> // aufs:/lower1:/lower2\0/upper
>
> Now
>
> lower
>
> points to
>
> // /lower1:/lower2\0
>
> and upper moves one final byte forward
>
> upper++;
>
> and we get
>
> // /upper
>
> voila.
>
>
> **Case B: "Missing upper or lower"**
>
> But now imagine doing the same stuff when we have:
>
> lxc.rootfs = aufs:/a
>
> abbreviating a bit we have:
>
> if (!(lower = strchr(dup, ':')))
> return -22;
Same typo: It should be (and is correct in the patch):
if (!(lower = strstr(dup, ":/")))
return -22;
> // lower = :/a
>
> lower++;
> // lower = /a
>
> upper = lower;
> // upper = lower = /a
>
> while ((tmp = strstr(++upper, ":/"))) {
> upper = tmp;
> }
> // upper = a
>
> but now we do
>
> if (--upper == lower)
> return -22;
>
> and now we compare
>
> // /a
>
> correctly with
>
> // /a
>
> and error out.
More information about the lxc-devel
mailing list