aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2017-06-28 07:41:22 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2017-06-28 07:41:22 -0400
commite85f82ff9b8ef503923a3be8ca6b5fd1908a7f3f (patch)
tree7c0b05231e998562d9fe83c41568f8f11ea480a6 /fs
parentc0bc126f97fb929b3ae02c1c62322645d70eb408 (diff)
ovl: copy-up: don't unlock between lookup and link
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") Cc: <stable@vger.kernel.org> # v4.11
Diffstat (limited to 'fs')
-rw-r--r--fs/overlayfs/copy_up.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index 7a44533f4bbf..ded8bfeb193e 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -330,15 +330,9 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
330 .link = link 330 .link = link
331 }; 331 };
332 332
333 upper = lookup_one_len(dentry->d_name.name, upperdir,
334 dentry->d_name.len);
335 err = PTR_ERR(upper);
336 if (IS_ERR(upper))
337 goto out;
338
339 err = security_inode_copy_up(dentry, &new_creds); 333 err = security_inode_copy_up(dentry, &new_creds);
340 if (err < 0) 334 if (err < 0)
341 goto out1; 335 goto out;
342 336
343 if (new_creds) 337 if (new_creds)
344 old_creds = override_creds(new_creds); 338 old_creds = override_creds(new_creds);
@@ -362,7 +356,7 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
362 } 356 }
363 357
364 if (err) 358 if (err)
365 goto out2; 359 goto out;
366 360
367 if (S_ISREG(stat->mode)) { 361 if (S_ISREG(stat->mode)) {
368 struct path upperpath; 362 struct path upperpath;
@@ -403,6 +397,14 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
403 if (err) 397 if (err)
404 goto out_cleanup; 398 goto out_cleanup;
405 399
400 upper = lookup_one_len(dentry->d_name.name, upperdir,
401 dentry->d_name.len);
402 if (IS_ERR(upper)) {
403 err = PTR_ERR(upper);
404 upper = NULL;
405 goto out_cleanup;
406 }
407
406 if (tmpfile) 408 if (tmpfile)
407 err = ovl_do_link(temp, udir, upper, true); 409 err = ovl_do_link(temp, udir, upper, true);
408 else 410 else
@@ -416,17 +418,15 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
416 418
417 /* Restore timestamps on parent (best effort) */ 419 /* Restore timestamps on parent (best effort) */
418 ovl_set_timestamps(upperdir, pstat); 420 ovl_set_timestamps(upperdir, pstat);
419out2: 421out:
420 dput(temp); 422 dput(temp);
421out1:
422 dput(upper); 423 dput(upper);
423out:
424 return err; 424 return err;
425 425
426out_cleanup: 426out_cleanup:
427 if (!tmpfile) 427 if (!tmpfile)
428 ovl_cleanup(wdir, temp); 428 ovl_cleanup(wdir, temp);
429 goto out2; 429 goto out;
430} 430}
431 431
432/* 432/*