linux/fs/overlayfs
Amir Goldstein 3ec9b3fafc ovl: fix lookup with middle layer opaque dir and absolute path redirects
As of now if we encounter an opaque dir while looking for a dentry, we set
d->last=true. This means that there is no need to look further in any of
the lower layers. This works fine as long as there are no redirets or
relative redircts. But what if there is an absolute redirect on the
children dentry of opaque directory. We still need to continue to look into
next lower layer. This patch fixes it.

Here is an example to demonstrate the issue. Say you have following setup.

upper:  /redirect (redirect=/a/b/c)
lower1: /a/[b]/c       ([b] is opaque) (c has absolute redirect=/a/b/d/)
lower0: /a/b/d/foo

Now "redirect" dir should merge with lower1:/a/b/c/ and lower0:/a/b/d.
Note, despite the fact lower1:/a/[b] is opaque, we need to continue to look
into lower0 because children c has an absolute redirect.

Following is a reproducer.

Watch me make foo disappear:

 $ mkdir lower middle upper work work2 merged
 $ mkdir lower/origin
 $ touch lower/origin/foo
 $ mount -t overlay none merged/ \
         -olowerdir=lower,upperdir=middle,workdir=work2
 $ mkdir merged/pure
 $ mv merged/origin merged/pure/redirect
 $ umount merged
 $ mount -t overlay none merged/ \
         -olowerdir=middle:lower,upperdir=upper,workdir=work
 $ mv merged/pure/redirect merged/redirect

Now you see foo inside a twice redirected merged dir:

 $ ls merged/redirect
 foo
 $ umount merged
 $ mount -t overlay none merged/ \
         -olowerdir=middle:lower,upperdir=upper,workdir=work

After mount cycle you don't see foo inside the same dir:

 $ ls merged/redirect

During middle layer lookup, the opaqueness of middle/pure is left in
the lookup state and then middle/pure/redirect is wrongly treated as
opaque.

Fixes: 02b69b284c ("ovl: lookup redirects")
Cc: <stable@vger.kernel.org> #v4.10
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2018-04-12 12:04:48 +02:00
..
copy_up.c ovl: copy up of disconnected dentries 2018-01-24 11:25:58 +01:00
dir.c ovl: whiteout index when union nlink drops to zero 2018-01-24 11:25:56 +01:00
export.c ovl: fix ptr_ret.cocci warnings 2018-02-26 12:45:20 +01:00
inode.c ovl: set i_ino to the value of st_ino for NFS export 2018-04-12 12:04:48 +02:00
Kconfig ovl: update Kconfig texts 2018-03-07 11:47:15 +01:00
Makefile ovl: encode pure upper file handles 2018-01-24 11:25:59 +01:00
namei.c ovl: fix lookup with middle layer opaque dir and absolute path redirects 2018-04-12 12:04:48 +02:00
overlayfs.h ovl: check lower ancestry on encode of lower dir file handle 2018-02-16 15:53:20 +01:00
ovl_entry.h ovl: store 'has_upper' and 'opaque' as bit flags 2018-01-24 11:25:58 +01:00
readdir.c ovl: whiteout orphan index entries on mount 2018-01-24 11:25:56 +01:00
super.c ovl: check lower ancestry on encode of lower dir file handle 2018-02-16 15:53:20 +01:00
util.c ovl: set i_ino to the value of st_ino for NFS export 2018-04-12 12:04:48 +02:00