aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@redhat.com>2016-09-06 13:40:32 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2016-09-19 10:50:59 -0400
commit8eac98b8beb4711c4ab61822cac077fd6660e820 (patch)
tree00f99d86265b7bae9c622c90fa4b72f0c1f6e788
parent2b6bc7f48d34a6043915beddbf53b981603737c8 (diff)
ovl: during copy up, switch to mounter's creds early
Now, we have the notion that copy up of a file is done with the creds of mounter of overlay filesystem (as opposed to task). Right now before we switch creds, we do some vfs_getattr() operations in the context of task and that itself can fail. We should do that getattr() using the creds of mounter instead. So this patch switches to mounter's creds early during copy up process so that even vfs_getattr() is done with mounter's creds. Do not call revert_creds() unless we have already called ovl_override_creds(). [Reported by Arnd Bergmann] Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r--fs/overlayfs/copy_up.c9
-rw-r--r--fs/overlayfs/inode.c13
2 files changed, 11 insertions, 11 deletions
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index abadbc30e013..796d06fafd09 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -348,7 +348,6 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
348 struct path parentpath; 348 struct path parentpath;
349 struct dentry *upperdir; 349 struct dentry *upperdir;
350 struct dentry *upperdentry; 350 struct dentry *upperdentry;
351 const struct cred *old_cred;
352 char *link = NULL; 351 char *link = NULL;
353 352
354 if (WARN_ON(!workdir)) 353 if (WARN_ON(!workdir))
@@ -369,8 +368,6 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
369 return PTR_ERR(link); 368 return PTR_ERR(link);
370 } 369 }
371 370
372 old_cred = ovl_override_creds(dentry->d_sb);
373
374 err = -EIO; 371 err = -EIO;
375 if (lock_rename(workdir, upperdir) != NULL) { 372 if (lock_rename(workdir, upperdir) != NULL) {
376 pr_err("overlayfs: failed to lock workdir+upperdir\n"); 373 pr_err("overlayfs: failed to lock workdir+upperdir\n");
@@ -391,7 +388,6 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
391 } 388 }
392out_unlock: 389out_unlock:
393 unlock_rename(workdir, upperdir); 390 unlock_rename(workdir, upperdir);
394 revert_creds(old_cred);
395 391
396 if (link) 392 if (link)
397 free_page((unsigned long) link); 393 free_page((unsigned long) link);
@@ -401,9 +397,9 @@ out_unlock:
401 397
402int ovl_copy_up(struct dentry *dentry) 398int ovl_copy_up(struct dentry *dentry)
403{ 399{
404 int err; 400 int err = 0;
401 const struct cred *old_cred = ovl_override_creds(dentry->d_sb);
405 402
406 err = 0;
407 while (!err) { 403 while (!err) {
408 struct dentry *next; 404 struct dentry *next;
409 struct dentry *parent; 405 struct dentry *parent;
@@ -435,6 +431,7 @@ int ovl_copy_up(struct dentry *dentry)
435 dput(parent); 431 dput(parent);
436 dput(next); 432 dput(next);
437 } 433 }
434 revert_creds(old_cred);
438 435
439 return err; 436 return err;
440} 437}
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index c75625c1efa3..ce5d7dfaf769 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -19,6 +19,7 @@ static int ovl_copy_up_truncate(struct dentry *dentry)
19 struct dentry *parent; 19 struct dentry *parent;
20 struct kstat stat; 20 struct kstat stat;
21 struct path lowerpath; 21 struct path lowerpath;
22 const struct cred *old_cred;
22 23
23 parent = dget_parent(dentry); 24 parent = dget_parent(dentry);
24 err = ovl_copy_up(parent); 25 err = ovl_copy_up(parent);
@@ -26,12 +27,14 @@ static int ovl_copy_up_truncate(struct dentry *dentry)
26 goto out_dput_parent; 27 goto out_dput_parent;
27 28
28 ovl_path_lower(dentry, &lowerpath); 29 ovl_path_lower(dentry, &lowerpath);
29 err = vfs_getattr(&lowerpath, &stat);
30 if (err)
31 goto out_dput_parent;
32 30
33 stat.size = 0; 31 old_cred = ovl_override_creds(dentry->d_sb);
34 err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat); 32 err = vfs_getattr(&lowerpath, &stat);
33 if (!err) {
34 stat.size = 0;
35 err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat);
36 }
37 revert_creds(old_cred);
35 38
36out_dput_parent: 39out_dput_parent:
37 dput(parent); 40 dput(parent);