ovl: redirect_dir=nofollow should not follow redirect for opaque lower
PATCH 1/1 ovl: redirect_dir=nofollow should not follow redirect for opaque lower
redirect_dir=nofollow should not follow a redirect. But in a specific configuration it can still follow it. For example try this.
$ mkdir -p lower0 lower1/foo upper work merged $ touch lower1/foo/lower-file.txt $ setfattr -n "trusted.overlay.opaque" -v "y" lower1/foo $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=on none merged $ cd merged $ mv foo foo-renamed $ umount merged
# mount again. This time with redirect_dir=nofollow $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=nofollow none merged $ ls merged/foo-renamed/ # This lists lower-file.txt, while it should not have.
Basically, we are doing redirect check after we check for d.stop. And if this is not last lower, and we find an opaque lower, d.stop will be set.
ovl_lookup_single()
if (!d->last && ovl_is_opaquedir(this)) {
d->stop = d->opaque = true;
goto out;
}To fix this, first check redirect is allowed. And after that check if d.stop has been set or not.
--- fs/overlayfs/namei.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/overlayfs/namei.c +3 -3
@@ -678,9 +678,6 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, stack[ctr].layer = lower.layer; ctr++; -if (d.stop) -break ; -/* * Following redirects can have security consequences: it's like * a symlink into the lower layer without the permission checks.
@@ -697,6 +694,9 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, goto out_put; } +if (d.stop) +break ; +if (d.redirect && d.redirect[0 ] =='/' && poe != roe) { poe = roe;
Signature · 1 line
2.13.6
Amir Goldstein
maintainerQuoted 26 lines · Vivek Goyal
redirect_dir=nofollow should not follow a redirect. But in a specific configuration it can still follow it. For example try this.
$ mkdir -p lower0 lower1/foo upper work merged $ touch lower1/foo/lower-file.txt $ setfattr -n "trusted.overlay.opaque" -v "y" lower1/foo $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=on none merged $ cd merged $ mv foo foo-renamed $ umount merged# mount again. This time with redirect_dir=nofollow $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=nofollow none merged $ ls merged/foo-renamed/ # This lists lower-file.txt, while it should not have.Basically, we are doing redirect check after we check for d.stop. And if this is not last lower, and we find an opaque lower, d.stop will be set.
ovl_lookup_single()if (!d->last && ovl_is_opaquedir(this)) { d->stop = d->opaque = true; goto out; }
Quoted 4 lines
To fix this, first check redirect is allowed. And after that check if d.stop has been set or not.
Signed-off-by Vivek Goyal <[email protected]>
Looks good.
Probably should have Fixes and Cc: stable
Quoted 31 lines
--- fs/overlayfs/namei.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)fs/overlayfs/namei.c +3
-4@@ -678,9 +678,6 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, stack[ctr].layer = lower.layer; ctr++; -if (d.stop) -break ; -/* * Following redirects can have security consequences: it's like * a symlink into the lower layer without the permission checks. @@ -697,6 +694,9 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, goto out_put; } +if (d.stop) +break ; +if (d.redirect && d.redirect[0 ] =='/' && poe != roe) { poe = roe; --2.13.6
Quoted 26 lines · Vivek Goyal
redirect_dir=nofollow should not follow a redirect. But in a specific configuration it can still follow it. For example try this.
$ mkdir -p lower0 lower1/foo upper work merged $ touch lower1/foo/lower-file.txt $ setfattr -n "trusted.overlay.opaque" -v "y" lower1/foo $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=on none merged $ cd merged $ mv foo foo-renamed $ umount merged# mount again. This time with redirect_dir=nofollow $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=nofollow none merged $ ls merged/foo-renamed/ # This lists lower-file.txt, while it should not have.Basically, we are doing redirect check after we check for d.stop. And if this is not last lower, and we find an opaque lower, d.stop will be set.
ovl_lookup_single()if (!d->last && ovl_is_opaquedir(this)) { d->stop = d->opaque = true; goto out; }
Quoted 4 lines
To fix this, first check redirect is allowed. And after that check if d.stop has been set or not.
Signed-off-by Vivek Goyal <[email protected]>
Thanks, applied.
Miklos
Amir Goldstein
maintainerQuoted 26 lines · Vivek Goyal
redirect_dir=nofollow should not follow a redirect. But in a specific configuration it can still follow it. For example try this.
$ mkdir -p lower0 lower1/foo upper work merged $ touch lower1/foo/lower-file.txt $ setfattr -n "trusted.overlay.opaque" -v "y" lower1/foo $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=on none merged $ cd merged $ mv foo foo-renamed $ umount merged# mount again. This time with redirect_dir=nofollow $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=nofollow none merged $ ls merged/foo-renamed/ # This lists lower-file.txt, while it should not have.Basically, we are doing redirect check after we check for d.stop. And if this is not last lower, and we find an opaque lower, d.stop will be set.
ovl_lookup_single()if (!d->last && ovl_is_opaquedir(this)) { d->stop = d->opaque = true; goto out; }
Quoted 4 lines
To fix this, first check redirect is allowed. And after that check if d.stop has been set or not.
Signed-off-by Vivek Goyal <[email protected]>
This is already in overlayfs-next, which is the branch you should be rebasing on..
Thanks,
Amir.
Amir Goldstein
maintainerQuoted 27 lines · Amir Goldstein
Quoted 26 lines · Vivek Goyal
redirect_dir=nofollow should not follow a redirect. But in a specific configuration it can still follow it. For example try this.
$ mkdir -p lower0 lower1/foo upper work merged $ touch lower1/foo/lower-file.txt $ setfattr -n "trusted.overlay.opaque" -v "y" lower1/foo $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=on none merged $ cd merged $ mv foo foo-renamed $ umount merged# mount again. This time with redirect_dir=nofollow $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=nofollow none merged $ ls merged/foo-renamed/ # This lists lower-file.txt, while it should not have.Basically, we are doing redirect check after we check for d.stop. And if this is not last lower, and we find an opaque lower, d.stop will be set.
ovl_lookup_single()if (!d->last && ovl_is_opaquedir(this)) { d->stop = d->opaque = true; goto out; }
Quoted 8 lines
Quoted 4 lines
To fix this, first check redirect is allowed. And after that check if d.stop has been set or not.
Signed-off-by Vivek Goyal <[email protected]>This is already in overlayfs-next, which is the branch you should be rebasing on..
Sorry, that was supposed to be a reply on first patch of metacopy series
Quoted 27 lines · Amir Goldstein
Quoted 26 lines · Vivek Goyal
redirect_dir=nofollow should not follow a redirect. But in a specific configuration it can still follow it. For example try this.
$ mkdir -p lower0 lower1/foo upper work merged $ touch lower1/foo/lower-file.txt $ setfattr -n "trusted.overlay.opaque" -v "y" lower1/foo $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=on none merged $ cd merged $ mv foo foo-renamed $ umount merged# mount again. This time with redirect_dir=nofollow $ mount -t overlay -o lowerdir=lower1:lower0,workdir=work,upperdir=upper,redirect_dir=nofollow none merged $ ls merged/foo-renamed/ # This lists lower-file.txt, while it should not have.Basically, we are doing redirect check after we check for d.stop. And if this is not last lower, and we find an opaque lower, d.stop will be set.
ovl_lookup_single()if (!d->last && ovl_is_opaquedir(this)) { d->stop = d->opaque = true; goto out; }
Quoted 7 lines
Quoted 4 lines
To fix this, first check redirect is allowed. And after that check if d.stop has been set or not.
Signed-off-by Vivek Goyal <[email protected]>This is already in overlayfs-next, which is the branch you should be rebasing on..
Hmm.., I generally work with linus's tree. I knew that this patch is in overlayfs-next. Assumed that it will be dropped while merging.
Next version I can rebase on top of overlayfs-next and post.
Vivek