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

Commit 86c3e00a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull overlayfs fixes from Miklos Szeredi:
 "Fix two bugs in copy-up code. One introduced in 4.11 and one in
  4.12-rc"

* 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
  ovl: don't set origin on broken lower hardlink
  ovl: copy-up: don't unlock between lookup and link
parents 4d8a991d fbaf94ee
Loading
Loading
Loading
Loading
+19 −14
Original line number Diff line number Diff line
@@ -330,15 +330,9 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
		.link = link
	};

	upper = lookup_one_len(dentry->d_name.name, upperdir,
			       dentry->d_name.len);
	err = PTR_ERR(upper);
	if (IS_ERR(upper))
		goto out;

	err = security_inode_copy_up(dentry, &new_creds);
	if (err < 0)
		goto out1;
		goto out;

	if (new_creds)
		old_creds = override_creds(new_creds);
@@ -362,7 +356,7 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
	}

	if (err)
		goto out2;
		goto out;

	if (S_ISREG(stat->mode)) {
		struct path upperpath;
@@ -398,10 +392,23 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,
	/*
	 * Store identifier of lower inode in upper inode xattr to
	 * allow lookup of the copy up origin inode.
	 *
	 * Don't set origin when we are breaking the association with a lower
	 * hard link.
	 */
	if (S_ISDIR(stat->mode) || stat->nlink == 1) {
		err = ovl_set_origin(dentry, lowerpath->dentry, temp);
		if (err)
			goto out_cleanup;
	}

	upper = lookup_one_len(dentry->d_name.name, upperdir,
			       dentry->d_name.len);
	if (IS_ERR(upper)) {
		err = PTR_ERR(upper);
		upper = NULL;
		goto out_cleanup;
	}

	if (tmpfile)
		err = ovl_do_link(temp, udir, upper, true);
@@ -416,17 +423,15 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir,

	/* Restore timestamps on parent (best effort) */
	ovl_set_timestamps(upperdir, pstat);
out2:
out:
	dput(temp);
out1:
	dput(upper);
out:
	return err;

out_cleanup:
	if (!tmpfile)
		ovl_cleanup(wdir, temp);
	goto out2;
	goto out;
}

/*