On Sat 01-06-13 19:05:54, Jonghwan Choi wrote:
> From: Jeff Mahoney <[email protected]>
>
> This patch looks like it should be in the 3.9-stable tree, should we apply
> it?
Yes, please do. Thanks.
Honza
>
> ------------------
>
> From: "Jeff Mahoney <[email protected]>"
>
> 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 <[email protected]>
> Signed-off-by: Jan Kara <[email protected]>
> Signed-off-by: Jonghwan Choi <[email protected]>
> ---
> 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;
>
> --
> 1.8.1.2
>
--
Jan Kara <[email protected]>
SUSE Labs, CR
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html