Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5820dc08 authored by Amir Goldstein's avatar Amir Goldstein Committed by Miklos Szeredi
Browse files

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: ("fd210b7d ovl: move copy up lock out")
Cc: <stable@vger.kernel.org> # v4.13
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent dc7ab677
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -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);
		}
+0 −20
Original line number Diff line number Diff line
@@ -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)
{
+1 −0
Original line number Diff line number Diff line
@@ -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)
{
+19 −0
Original line number Diff line number Diff line
@@ -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;
}