On Sat 01-06-13 19:05:54, Jonghwan Choi wrote: > From: Jeff Mahoney <jeffm@xxxxxxxx> > > 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 <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; > > -- > 1.8.1.2 > -- Jan Kara <jack@xxxxxxx> SUSE Labs, CR -- 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