Re: [PATCH 3.9-stable] reiserfs: fix problems with chowning setuid file w/ xattrs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jonghwan Choi <jhbird.choi@xxxxxxxxx> writes:

> From: Jeff Mahoney <jeffm@xxxxxxxx>
>
> This patch looks like it should be in the 3.9-stable tree, should we apply
> it?

This patch seems to be applicable to all the other stable trees as
well.  I'm queuing it for the 3.5 kernel.

Cheers,
-- 
Luis

>
> ------------------
>
> From: "Jeff Mahoney <jeffm@xxxxxxxx>"
>
> commit 4a8570112b76a63ad21cfcbe2783f98f7fd5ba1b upstream
>
> reiserfs_chown_xattrs() takes the iattr struct passed into ->setattr
> and uses it to iterate over all the attrs associated with a file to change
> ownership of xattrs (and transfer quota associated with the xattr files).
>
> When the setuid bit is cleared during chown, ATTR_MODE and iattr->ia_mode
> are passed to all the xattrs as well. This means that the xattr directory
> will have S_IFREG added to its mode bits.
>
> This has been prevented in practice by a missing IS_PRIVATE check
> in reiserfs_acl_chmod, which caused a double-lock to occur while holding
> the write lock. Since the file system was completely locked up, the
> writeout of the corrupted mode never happened.
>
> This patch temporarily clears everything but ATTR_UID|ATTR_GID for the
> calls to reiserfs_setattr and adds the missing IS_PRIVATE check.
>
> Signed-off-by: Jeff Mahoney <jeffm@xxxxxxxx>
> Signed-off-by: Jan Kara <jack@xxxxxxx>
> Signed-off-by: Jonghwan Choi <jhbird.choi@xxxxxxxxxxx>
> ---
>  fs/reiserfs/xattr.c     | 14 +++++++++++++-
>  fs/reiserfs/xattr_acl.c |  3 +++
>  2 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
> index 4cce1d9..821bcf7 100644
> --- a/fs/reiserfs/xattr.c
> +++ b/fs/reiserfs/xattr.c
> @@ -318,7 +318,19 @@ static int delete_one_xattr(struct dentry *dentry, void *data)
>  static int chown_one_xattr(struct dentry *dentry, void *data)
>  {
>  	struct iattr *attrs = data;
> -	return reiserfs_setattr(dentry, attrs);
> +	int ia_valid = attrs->ia_valid;
> +	int err;
> +
> +	/*
> +	 * We only want the ownership bits. Otherwise, we'll do
> +	 * things like change a directory to a regular file if
> +	 * ATTR_MODE is set.
> +	 */
> +	attrs->ia_valid &= (ATTR_UID|ATTR_GID);
> +	err = reiserfs_setattr(dentry, attrs);
> +	attrs->ia_valid = ia_valid;
> +
> +	return err;
>  }
>  
>  /* No i_mutex, but the inode is unconnected. */
> diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
> index d7c01ef..6c8767f 100644
> --- a/fs/reiserfs/xattr_acl.c
> +++ b/fs/reiserfs/xattr_acl.c
> @@ -443,6 +443,9 @@ int reiserfs_acl_chmod(struct inode *inode)
>  	int depth;
>  	int error;
>  
> +	if (IS_PRIVATE(inode))
> +		return 0;
> +
>  	if (S_ISLNK(inode->i_mode))
>  		return -EOPNOTSUPP;
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]