Skip to content

Commit

Permalink
ovl: fix missing unlock_rename() in ovl_do_copy_up()
Browse files Browse the repository at this point in the history
Use the ovl_lock_rename_workdir() helper which requires
unlock_rename() only on lock success.

Fixes: ("fd210b7d67ee ovl: move copy up lock out")
Cc: <[email protected]> # v4.13
Signed-off-by: Amir Goldstein <[email protected]>
Signed-off-by: Miklos Szeredi <[email protected]>
  • Loading branch information
amir73il authored and Miklos Szeredi committed Oct 5, 2017
1 parent dc7ab67 commit 5820dc0
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 24 deletions.
6 changes: 2 additions & 4 deletions fs/overlayfs/copy_up.c
Original file line number Diff line number Diff line change
Expand Up @@ -561,10 +561,8 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
c->tmpfile = true;
err = ovl_copy_up_locked(c);
} else {
err = -EIO;
if (lock_rename(c->workdir, c->destdir) != NULL) {
pr_err("overlayfs: failed to lock workdir+upperdir\n");
} else {
err = ovl_lock_rename_workdir(c->workdir, c->destdir);
if (!err) {
err = ovl_copy_up_locked(c);
unlock_rename(c->workdir, c->destdir);
}
Expand Down
20 changes: 0 additions & 20 deletions fs/overlayfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,26 +216,6 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
return err;
}

static int ovl_lock_rename_workdir(struct dentry *workdir,
struct dentry *upperdir)
{
/* Workdir should not be the same as upperdir */
if (workdir == upperdir)
goto err;

/* Workdir should not be subdir of upperdir and vice versa */
if (lock_rename(workdir, upperdir) != NULL)
goto err_unlock;

return 0;

err_unlock:
unlock_rename(workdir, upperdir);
err:
pr_err("overlayfs: failed to lock workdir+upperdir\n");
return -EIO;
}

static struct dentry *ovl_clear_empty(struct dentry *dentry,
struct list_head *list)
{
Expand Down
1 change: 1 addition & 0 deletions fs/overlayfs/overlayfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ bool ovl_inuse_trylock(struct dentry *dentry);
void ovl_inuse_unlock(struct dentry *dentry);
int ovl_nlink_start(struct dentry *dentry, bool *locked);
void ovl_nlink_end(struct dentry *dentry, bool locked);
int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir);

static inline bool ovl_is_impuredir(struct dentry *dentry)
{
Expand Down
19 changes: 19 additions & 0 deletions fs/overlayfs/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,3 +560,22 @@ void ovl_nlink_end(struct dentry *dentry, bool locked)
mutex_unlock(&OVL_I(d_inode(dentry))->lock);
}
}

int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir)
{
/* Workdir should not be the same as upperdir */
if (workdir == upperdir)
goto err;

/* Workdir should not be subdir of upperdir and vice versa */
if (lock_rename(workdir, upperdir) != NULL)
goto err_unlock;

return 0;

err_unlock:
unlock_rename(workdir, upperdir);
err:
pr_err("overlayfs: failed to lock workdir+upperdir\n");
return -EIO;
}

0 comments on commit 5820dc0

Please sign in to comment.