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

Commit db78b877 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Al Viro
Browse files

always call inode_change_ok early in ->setattr



Make sure we call inode_change_ok before doing any changes in ->setattr,
and make sure to call it even if our fs wants to ignore normal UNIX
permissions, but use the ATTR_FORCE to skip those.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 1025774c
Loading
Loading
Loading
Loading
+13 −16
Original line number Diff line number Diff line
@@ -1796,14 +1796,12 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)

	xid = GetXid();

	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
		/* check if we have permission to change attrs */
	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
		attrs->ia_valid |= ATTR_FORCE;

	rc = inode_change_ok(inode, attrs);
	if (rc < 0)
		goto out;
		else
			rc = 0;
	}

	full_path = build_path_from_dentry(direntry);
	if (full_path == NULL) {
@@ -1934,14 +1932,13 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
	cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
		 direntry->d_name.name, attrs->ia_valid);

	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
		/* check if we have permission to change attrs */
	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
		attrs->ia_valid |= ATTR_FORCE;

	rc = inode_change_ok(inode, attrs);
	if (rc < 0) {
		FreeXid(xid);
		return rc;
		} else
			rc = 0;
	}

	full_path = build_path_from_dentry(direntry);
+15 −15
Original line number Diff line number Diff line
@@ -387,21 +387,6 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
	unsigned int ia_valid;
	int error;

	/*
	 * Expand the file. Since inode_setattr() updates ->i_size
	 * before calling the ->truncate(), but FAT needs to fill the
	 * hole before it. XXX: this is no longer true with new truncate
	 * sequence.
	 */
	if (attr->ia_valid & ATTR_SIZE) {
		if (attr->ia_size > inode->i_size) {
			error = fat_cont_expand(inode, attr->ia_size);
			if (error || attr->ia_valid == ATTR_SIZE)
				goto out;
			attr->ia_valid &= ~ATTR_SIZE;
		}
	}

	/* Check for setting the inode time. */
	ia_valid = attr->ia_valid;
	if (ia_valid & TIMES_SET_FLAGS) {
@@ -417,6 +402,21 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
		goto out;
	}

	/*
	 * Expand the file. Since inode_setattr() updates ->i_size
	 * before calling the ->truncate(), but FAT needs to fill the
	 * hole before it. XXX: this is no longer true with new truncate
	 * sequence.
	 */
	if (attr->ia_valid & ATTR_SIZE) {
		if (attr->ia_size > inode->i_size) {
			error = fat_cont_expand(inode, attr->ia_size);
			if (error || attr->ia_valid == ATTR_SIZE)
				goto out;
			attr->ia_valid &= ~ATTR_SIZE;
		}
	}

	if (((attr->ia_valid & ATTR_UID) &&
	     (attr->ia_uid != sbi->options.fs_uid)) ||
	    ((attr->ia_valid & ATTR_GID) &&
+6 −5
Original line number Diff line number Diff line
@@ -1270,11 +1270,12 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
	if (!fuse_allow_task(fc, current))
		return -EACCES;

	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
	if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
		attr->ia_valid |= ATTR_FORCE;

	err = inode_change_ok(inode, attr);
	if (err)
		return err;
	}

	if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc)
		return 0;
+4 −4
Original line number Diff line number Diff line
@@ -232,15 +232,15 @@ static int logfs_setattr(struct dentry *dentry, struct iattr *attr)
	struct inode *inode = dentry->d_inode;
	int err = 0;

	if (attr->ia_valid & ATTR_SIZE) {
		err = logfs_truncate(inode, attr->ia_size);
	err = inode_change_ok(inode, attr);
	if (err)
		return err;
	}

	err = inode_change_ok(inode, attr);
	if (attr->ia_valid & ATTR_SIZE) {
		err = logfs_truncate(inode, attr->ia_size);
		if (err)
			return err;
	}

	setattr_copy(inode, attr);
	mark_inode_dirty(inode);
+4 −4
Original line number Diff line number Diff line
@@ -3084,6 +3084,10 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
	int depth;
	int error;

	error = inode_change_ok(inode, attr);
	if (error)
		return error;

	/* must be turned off for recursive notify_change calls */
	ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);

@@ -3133,10 +3137,6 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
		goto out;
	}

	error = inode_change_ok(inode, attr);
	if (error)
		goto out;

	if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
	    (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
		struct reiserfs_transaction_handle th;
Loading