From: Greg Kroah-Hartman Date: Mon, 26 Apr 2010 22:16:22 +0000 (-0700) Subject: .31 patches X-Git-Tag: v2.6.32.13~27 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9dbcaf2f40a5774a9ab8ddfd17e8b63a0f7e2694;p=thirdparty%2Fkernel%2Fstable-queue.git .31 patches --- diff --git a/queue-2.6.31/reiserfs-fix-corruption-during-shrinking-of-xattrs.patch b/queue-2.6.31/reiserfs-fix-corruption-during-shrinking-of-xattrs.patch new file mode 100644 index 00000000000..d217f0f37fb --- /dev/null +++ b/queue-2.6.31/reiserfs-fix-corruption-during-shrinking-of-xattrs.patch @@ -0,0 +1,52 @@ +From fb2162df74bb19552db3d988fd11c787cf5fad56 Mon Sep 17 00:00:00 2001 +From: Jeff Mahoney +Date: Fri, 23 Apr 2010 13:17:41 -0400 +Subject: reiserfs: fix corruption during shrinking of xattrs + +From: Jeff Mahoney + +commit fb2162df74bb19552db3d988fd11c787cf5fad56 upstream. + +Commit 48b32a3553a54740d236b79a90f20147a25875e3 ("reiserfs: use generic +xattr handlers") introduced a problem that causes corruption when extended +attributes are replaced with a smaller value. + +The issue is that the reiserfs_setattr to shrink the xattr file was moved +from before the write to after the write. + +The root issue has always been in the reiserfs xattr code, but was papered +over by the fact that in the shrink case, the file would just be expanded +again while the xattr was written. + +The end result is that the last 8 bytes of xattr data are lost. + +This patch fixes it to use new_size. + +Addresses https://bugzilla.kernel.org/show_bug.cgi?id=14826 + +Signed-off-by: Jeff Mahoney +Reported-by: Christian Kujau +Tested-by: Christian Kujau +Cc: Edward Shishkin +Cc: Jethro Beekman +Cc: Greg Surbey +Cc: Marco Gatti +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/reiserfs/xattr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/reiserfs/xattr.c ++++ b/fs/reiserfs/xattr.c +@@ -536,7 +536,7 @@ reiserfs_xattr_set_handle(struct reiserf + if (!err && new_size < i_size_read(dentry->d_inode)) { + struct iattr newattrs = { + .ia_ctime = current_fs_time(inode->i_sb), +- .ia_size = buffer_size, ++ .ia_size = new_size, + .ia_valid = ATTR_SIZE | ATTR_CTIME, + }; + mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); diff --git a/queue-2.6.31/reiserfs-fix-permissions-on-.reiserfs_priv.patch b/queue-2.6.31/reiserfs-fix-permissions-on-.reiserfs_priv.patch new file mode 100644 index 00000000000..64a0654c01d --- /dev/null +++ b/queue-2.6.31/reiserfs-fix-permissions-on-.reiserfs_priv.patch @@ -0,0 +1,91 @@ +From cac36f707119b792b2396aed371d6b5cdc194890 Mon Sep 17 00:00:00 2001 +From: Jeff Mahoney +Date: Fri, 23 Apr 2010 13:17:37 -0400 +Subject: reiserfs: fix permissions on .reiserfs_priv + +From: Jeff Mahoney + +commit cac36f707119b792b2396aed371d6b5cdc194890 upstream. + +Commit 677c9b2e393a0cd203bd54e9c18b012b2c73305a ("reiserfs: remove +privroot hiding in lookup") removed the magic from the lookup code to hide +the .reiserfs_priv directory since it was getting loaded at mount-time +instead. The intent was that the entry would be hidden from the user via +a poisoned d_compare, but this was faulty. + +This introduced a security issue where unprivileged users could access and +modify extended attributes or ACLs belonging to other users, including +root. + +This patch resolves the issue by properly hiding .reiserfs_priv. This was +the intent of the xattr poisoning code, but it appears to have never +worked as expected. This is fixed by using d_revalidate instead of +d_compare. + +This patch makes -oexpose_privroot a no-op. I'm fine leaving it this way. +The effort involved in working out the corner cases wrt permissions and +caching outweigh the benefit of the feature. + +Signed-off-by: Jeff Mahoney +Acked-by: Edward Shishkin +Reported-by: Matt McCutchen +Tested-by: Matt McCutchen +Cc: Frederic Weisbecker +Cc: Al Viro +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/reiserfs/dir.c | 2 -- + fs/reiserfs/xattr.c | 17 ++++------------- + 2 files changed, 4 insertions(+), 15 deletions(-) + +--- a/fs/reiserfs/dir.c ++++ b/fs/reiserfs/dir.c +@@ -45,8 +45,6 @@ static inline bool is_privroot_deh(struc + struct reiserfs_de_head *deh) + { + struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root; +- if (reiserfs_expose_privroot(dir->d_sb)) +- return 0; + return (dir == dir->d_parent && privroot->d_inode && + deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid); + } +--- a/fs/reiserfs/xattr.c ++++ b/fs/reiserfs/xattr.c +@@ -952,21 +952,13 @@ int reiserfs_permission(struct inode *in + return generic_permission(inode, mask, NULL); + } + +-/* This will catch lookups from the fs root to .reiserfs_priv */ +-static int +-xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name) ++static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd) + { +- struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root; +- if (container_of(q1, struct dentry, d_name) == priv_root) +- return -ENOENT; +- if (q1->len == name->len && +- !memcmp(q1->name, name->name, name->len)) +- return 0; +- return 1; ++ return -EPERM; + } + + static const struct dentry_operations xattr_lookup_poison_ops = { +- .d_compare = xattr_lookup_poison, ++ .d_revalidate = xattr_hide_revalidate, + }; + + int reiserfs_lookup_privroot(struct super_block *s) +@@ -980,8 +972,7 @@ int reiserfs_lookup_privroot(struct supe + strlen(PRIVROOT_NAME)); + if (!IS_ERR(dentry)) { + REISERFS_SB(s)->priv_root = dentry; +- if (!reiserfs_expose_privroot(s)) +- s->s_root->d_op = &xattr_lookup_poison_ops; ++ dentry->d_op = &xattr_lookup_poison_ops; + if (dentry->d_inode) + dentry->d_inode->i_flags |= S_PRIVATE; + } else diff --git a/queue-2.6.31/series b/queue-2.6.31/series index 9091fb02c6d..101c3747369 100644 --- a/queue-2.6.31/series +++ b/queue-2.6.31/series @@ -1 +1,3 @@ alsa-mixart-range-checking-proc-file.patch +reiserfs-fix-permissions-on-.reiserfs_priv.patch +reiserfs-fix-corruption-during-shrinking-of-xattrs.patch