aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2017-09-25 09:39:55 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2017-10-05 09:53:18 -0400
commit5820dc0888d302ac05f8b91ffdf7e4e53b4fbf53 (patch)
treee22ae933b338fe9a51f34cef6658d82484aaff91
parentdc7ab6773e8171e07f16fd0df0c5eea28c899503 (diff)
ovl: fix missing unlock_rename() in ovl_do_copy_up()
Use the ovl_lock_rename_workdir() helper which requires unlock_rename() only on lock success. Fixes: ("fd210b7d67ee ovl: move copy up lock out") Cc: <stable@vger.kernel.org> # v4.13 Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r--fs/overlayfs/copy_up.c6
-rw-r--r--fs/overlayfs/dir.c20
-rw-r--r--fs/overlayfs/overlayfs.h1
-rw-r--r--fs/overlayfs/util.c19
4 files changed, 22 insertions, 24 deletions
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index aad97b30d5e6..c441f9387a1b 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -561,10 +561,8 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
561 c->tmpfile = true; 561 c->tmpfile = true;
562 err = ovl_copy_up_locked(c); 562 err = ovl_copy_up_locked(c);
563 } else { 563 } else {
564 err = -EIO; 564 err = ovl_lock_rename_workdir(c->workdir, c->destdir);
565 if (lock_rename(c->workdir, c->destdir) != NULL) { 565 if (!err) {
566 pr_err("overlayfs: failed to lock workdir+upperdir\n");
567 } else {
568 err = ovl_copy_up_locked(c); 566 err = ovl_copy_up_locked(c);
569 unlock_rename(c->workdir, c->destdir); 567 unlock_rename(c->workdir, c->destdir);
570 } 568 }
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 3309b1912241..cc961a3bd3bd 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -216,26 +216,6 @@ out_unlock:
216 return err; 216 return err;
217} 217}
218 218
219static int ovl_lock_rename_workdir(struct dentry *workdir,
220 struct dentry *upperdir)
221{
222 /* Workdir should not be the same as upperdir */
223 if (workdir == upperdir)
224 goto err;
225
226 /* Workdir should not be subdir of upperdir and vice versa */
227 if (lock_rename(workdir, upperdir) != NULL)
228 goto err_unlock;
229
230 return 0;
231
232err_unlock:
233 unlock_rename(workdir, upperdir);
234err:
235 pr_err("overlayfs: failed to lock workdir+upperdir\n");
236 return -EIO;
237}
238
239static struct dentry *ovl_clear_empty(struct dentry *dentry, 219static struct dentry *ovl_clear_empty(struct dentry *dentry,
240 struct list_head *list) 220 struct list_head *list)
241{ 221{
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index d4e8c1a08fb0..c706a6f99928 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -235,6 +235,7 @@ bool ovl_inuse_trylock(struct dentry *dentry);
235void ovl_inuse_unlock(struct dentry *dentry); 235void ovl_inuse_unlock(struct dentry *dentry);
236int ovl_nlink_start(struct dentry *dentry, bool *locked); 236int ovl_nlink_start(struct dentry *dentry, bool *locked);
237void ovl_nlink_end(struct dentry *dentry, bool locked); 237void ovl_nlink_end(struct dentry *dentry, bool locked);
238int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir);
238 239
239static inline bool ovl_is_impuredir(struct dentry *dentry) 240static inline bool ovl_is_impuredir(struct dentry *dentry)
240{ 241{
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 7ae33d225a67..b9b239fa5cfd 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -560,3 +560,22 @@ void ovl_nlink_end(struct dentry *dentry, bool locked)
560 mutex_unlock(&OVL_I(d_inode(dentry))->lock); 560 mutex_unlock(&OVL_I(d_inode(dentry))->lock);
561 } 561 }
562} 562}
563
564int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir)
565{
566 /* Workdir should not be the same as upperdir */
567 if (workdir == upperdir)
568 goto err;
569
570 /* Workdir should not be subdir of upperdir and vice versa */
571 if (lock_rename(workdir, upperdir) != NULL)
572 goto err_unlock;
573
574 return 0;
575
576err_unlock:
577 unlock_rename(workdir, upperdir);
578err:
579 pr_err("overlayfs: failed to lock workdir+upperdir\n");
580 return -EIO;
581}