[PATCH 4.11 45/84] ovl: copy-up: dont unlock between lookup and link

Greg Kroah-Hartman
2017-07-03T13:48:24Z

From: Miklos Szeredi <mszeredi@redhat.com>

commit e85f82ff9b8ef503923a3be8ca6b5fd1908a7f3f upstream.

Nothing prevents mischief on upper layer while we are busy copying up the
data.

Move the lookup right before the looked up dentry is actually used.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Fixes: 01ad3eb8a073 ("ovl: concurrent copy up of regular files")
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
fs/overlayfs/copy_up.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)

--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -252,15 +252,9 @@ static int ovl_copy_up_locked(struct den
.link = link
};

- upper = lookup_one_len(dentry->d_name.name, upperdir,
- dentry->d_name.len);
- err = PTR_ERR(upper);
- if (IS_ERR(upper))
- goto out;
-
err = security_inode_copy_up(dentry, &new_creds);
if (err < 0)
- goto out1;
+ goto out;

if (new_creds)
old_creds = override_creds(new_creds);
@@ -284,7 +278,7 @@ static int ovl_copy_up_locked(struct den
}

if (err)
- goto out2;
+ goto out;

if (S_ISREG(stat->mode)) {
struct path upperpath;
@@ -317,6 +311,14 @@ static int ovl_copy_up_locked(struct den
if (err)
goto out_cleanup;

+ upper = lookup_one_len(dentry->d_name.name, upperdir,
+ dentry->d_name.len);
+ if (IS_ERR(upper)) {
+ err = PTR_ERR(upper);
+ upper = NULL;
+ goto out_cleanup;
+ }
+
if (tmpfile)
err = ovl_do_link(temp, udir, upper, true);
else
@@ -330,17 +332,15 @@ static int ovl_copy_up_locked(struct den

/* Restore timestamps on parent (best effort) */
ovl_set_timestamps(upperdir, pstat);
-out2:
+out:
dput(temp);
-out1:
dput(upper);
-out:
return err;

out_cleanup:
if (!tmpfile)
ovl_cleanup(wdir, temp);
- goto out2;
+ goto out;
}

/*