Commit 4cb2c00c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull overlayfs fixes from Miklos Szeredi:

 - Fix capability conversion and minor overlayfs bugs that are related
   to the unprivileged overlay mounts introduced in this cycle.

 - Fix two recent (v5.10) and one old (v4.10) bug.

 - Clean up security xattr copy-up (related to a SELinux regression).

* tag 'ovl-fixes-5.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
  ovl: implement volatile-specific fsync error behaviour
  ovl: skip getxattr of security labels
  ovl: fix dentry leak in ovl_get_redirect
  ovl: avoid deadlock on directory ioctl
  cap: fix conversions on getxattr
  ovl: perform vfs_getxattr() with mounter creds
  ovl: add warning on user_ns mismatch
parents 61556703 335d3fc5
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -586,6 +586,14 @@ without significant effort.
The advantage of mounting with the "volatile" option is that all forms of
sync calls to the upper filesystem are omitted.

In order to avoid a giving a false sense of safety, the syncfs (and fsync)
semantics of volatile mounts are slightly different than that of the rest of
VFS.  If any writeback error occurs on the upperdir's filesystem after a
volatile mount takes place, all sync functions will return an error.  Once this
condition is reached, the filesystem will not recover, and every subsequent sync
call will return an error, even if the upperdir has not experience a new error
since the last sync call.

When overlay is mounted with "volatile" option, the directory
"$workdir/work/incompat/volatile" is created.  During next mount, overlay
checks for this directory and refuses to mount if present. This is a strong
+8 −7
Original line number Diff line number Diff line
@@ -84,6 +84,14 @@ int ovl_copy_xattr(struct super_block *sb, struct dentry *old,

		if (ovl_is_private_xattr(sb, name))
			continue;

		error = security_inode_copy_up_xattr(name);
		if (error < 0 && error != -EOPNOTSUPP)
			break;
		if (error == 1) {
			error = 0;
			continue; /* Discard */
		}
retry:
		size = vfs_getxattr(old, name, value, value_size);
		if (size == -ERANGE)
@@ -107,13 +115,6 @@ int ovl_copy_xattr(struct super_block *sb, struct dentry *old,
			goto retry;
		}

		error = security_inode_copy_up_xattr(name);
		if (error < 0 && error != -EOPNOTSUPP)
			break;
		if (error == 1) {
			error = 0;
			continue; /* Discard */
		}
		error = vfs_setxattr(new, name, value, size, 0);
		if (error) {
			if (error != -EOPNOTSUPP || ovl_must_copy_xattr(name))
+1 −1
Original line number Diff line number Diff line
@@ -992,8 +992,8 @@ static char *ovl_get_redirect(struct dentry *dentry, bool abs_redirect)

		buflen -= thislen;
		memcpy(&buf[buflen], name, thislen);
		tmp = dget_dlock(d->d_parent);
		spin_unlock(&d->d_lock);
		tmp = dget_parent(d);

		dput(d);
		d = tmp;
+3 −2
Original line number Diff line number Diff line
@@ -398,8 +398,9 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
	const struct cred *old_cred;
	int ret;

	if (!ovl_should_sync(OVL_FS(file_inode(file)->i_sb)))
		return 0;
	ret = ovl_sync_status(OVL_FS(file_inode(file)->i_sb));
	if (ret <= 0)
		return ret;

	ret = ovl_real_fdget_meta(file, &real, !datasync);
	if (ret)
+2 −0
Original line number Diff line number Diff line
@@ -352,7 +352,9 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
		goto out;

	if (!value && !upperdentry) {
		old_cred = ovl_override_creds(dentry->d_sb);
		err = vfs_getxattr(realdentry, name, NULL, 0);
		revert_creds(old_cred);
		if (err < 0)
			goto out_drop_write;
	}
Loading