]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 5 Jun 2012 03:20:35 +0000 (20:20 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 5 Jun 2012 03:20:35 +0000 (20:20 -0700)
added patches:
ext4-add-ext4_mb_unload_buddy-in-the-error-path.patch
ext4-add-missing-save_error_info-to-ext4_error.patch
ext4-disallow-hard-linked-directory-in-ext4_lookup.patch
ext4-don-t-trash-state-flags-in-ext4_ioc_setflags.patch
ext4-fix-potential-integer-overflow-in-alloc_flex_gd.patch
ext4-fix-potential-null-dereference-in-ext4_free_inodes_counts.patch
ext4-force-ro-mount-if-ext4_setup_super-fails.patch
ext4-remove-mb_groups-before-tearing-down-the-buddy_cache.patch

queue-3.4/ext4-add-ext4_mb_unload_buddy-in-the-error-path.patch [new file with mode: 0644]
queue-3.4/ext4-add-missing-save_error_info-to-ext4_error.patch [new file with mode: 0644]
queue-3.4/ext4-disallow-hard-linked-directory-in-ext4_lookup.patch [new file with mode: 0644]
queue-3.4/ext4-don-t-trash-state-flags-in-ext4_ioc_setflags.patch [new file with mode: 0644]
queue-3.4/ext4-fix-potential-integer-overflow-in-alloc_flex_gd.patch [new file with mode: 0644]
queue-3.4/ext4-fix-potential-null-dereference-in-ext4_free_inodes_counts.patch [new file with mode: 0644]
queue-3.4/ext4-force-ro-mount-if-ext4_setup_super-fails.patch [new file with mode: 0644]
queue-3.4/ext4-remove-mb_groups-before-tearing-down-the-buddy_cache.patch [new file with mode: 0644]
queue-3.4/series

diff --git a/queue-3.4/ext4-add-ext4_mb_unload_buddy-in-the-error-path.patch b/queue-3.4/ext4-add-ext4_mb_unload_buddy-in-the-error-path.patch
new file mode 100644 (file)
index 0000000..5919ab2
--- /dev/null
@@ -0,0 +1,30 @@
+From 02b7831019ea4e7994968c84b5826fa8b248ffc8 Mon Sep 17 00:00:00 2001
+From: Salman Qazi <sqazi@google.com>
+Date: Thu, 31 May 2012 23:51:27 -0400
+Subject: ext4: add ext4_mb_unload_buddy in the error path
+
+From: Salman Qazi <sqazi@google.com>
+
+commit 02b7831019ea4e7994968c84b5826fa8b248ffc8 upstream.
+
+ext4_free_blocks fails to pair an ext4_mb_load_buddy with a matching
+ext4_mb_unload_buddy when it fails a memory allocation.
+
+Signed-off-by: Salman Qazi <sqazi@google.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/mballoc.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -4636,6 +4636,7 @@ do_more:
+                */
+               new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS);
+               if (!new_entry) {
++                      ext4_mb_unload_buddy(&e4b);
+                       err = -ENOMEM;
+                       goto error_return;
+               }
diff --git a/queue-3.4/ext4-add-missing-save_error_info-to-ext4_error.patch b/queue-3.4/ext4-add-missing-save_error_info-to-ext4_error.patch
new file mode 100644 (file)
index 0000000..6929ad2
--- /dev/null
@@ -0,0 +1,34 @@
+From f3fc0210c0fc91900766c995f089c39170e68305 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 30 May 2012 23:00:16 -0400
+Subject: ext4: add missing save_error_info() to ext4_error()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit f3fc0210c0fc91900766c995f089c39170e68305 upstream.
+
+The ext4_error() function is missing a call to save_error_info().
+Since this is the function which marks the file system as containing
+an error, this oversight (which was introduced in 2.6.36) is quite
+significant, and should be backported to older stable kernels with
+high urgency.
+
+Reported-by: Ken Sumrall <ksumrall@google.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Cc: ksumrall@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -497,6 +497,7 @@ void __ext4_error(struct super_block *sb
+       printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: comm %s: %pV\n",
+              sb->s_id, function, line, current->comm, &vaf);
+       va_end(args);
++      save_error_info(sb, function, line);
+       ext4_handle_error(sb);
+ }
diff --git a/queue-3.4/ext4-disallow-hard-linked-directory-in-ext4_lookup.patch b/queue-3.4/ext4-disallow-hard-linked-directory-in-ext4_lookup.patch
new file mode 100644 (file)
index 0000000..e21a7f1
--- /dev/null
@@ -0,0 +1,36 @@
+From 7e936b737211e6b54e34b71a827e56b872e958d8 Mon Sep 17 00:00:00 2001
+From: Andreas Dilger <adilger@dilger.ca>
+Date: Mon, 28 May 2012 17:02:25 -0400
+Subject: ext4: disallow hard-linked directory in ext4_lookup
+
+From: Andreas Dilger <adilger@dilger.ca>
+
+commit 7e936b737211e6b54e34b71a827e56b872e958d8 upstream.
+
+A hard-linked directory to its parent can cause the VFS to deadlock,
+and is a sign of a corrupted file system.  So detect this case in
+ext4_lookup(), before the rmdir() lockup scenario can take place.
+
+Signed-off-by: Andreas Dilger <adilger@dilger.ca>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/namei.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1037,6 +1037,12 @@ static struct dentry *ext4_lookup(struct
+                       EXT4_ERROR_INODE(dir, "bad inode number: %u", ino);
+                       return ERR_PTR(-EIO);
+               }
++              if (unlikely(ino == dir->i_ino)) {
++                      EXT4_ERROR_INODE(dir, "'%.*s' linked to parent dir",
++                                       dentry->d_name.len,
++                                       dentry->d_name.name);
++                      return ERR_PTR(-EIO);
++              }
+               inode = ext4_iget(dir->i_sb, ino);
+               if (inode == ERR_PTR(-ESTALE)) {
+                       EXT4_ERROR_INODE(dir,
diff --git a/queue-3.4/ext4-don-t-trash-state-flags-in-ext4_ioc_setflags.patch b/queue-3.4/ext4-don-t-trash-state-flags-in-ext4_ioc_setflags.patch
new file mode 100644 (file)
index 0000000..836cd0e
--- /dev/null
@@ -0,0 +1,52 @@
+From 79906964a187c405db72a3abc60eb9b50d804fbc Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 31 May 2012 23:46:01 -0400
+Subject: ext4: don't trash state flags in EXT4_IOC_SETFLAGS
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 79906964a187c405db72a3abc60eb9b50d804fbc upstream.
+
+In commit 353eb83c we removed i_state_flags with 64-bit longs, But
+when handling the EXT4_IOC_SETFLAGS ioctl, we replace i_flags
+directly, which trashes the state flags which are stored in the high
+32-bits of i_flags on 64-bit platforms.  So use the the
+ext4_{set,clear}_inode_flags() functions which use atomic bit
+manipulation functions instead.
+
+Reported-by: Tao Ma <boyu.mt@taobao.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ioctl.c |   12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -38,7 +38,7 @@ long ext4_ioctl(struct file *filp, unsig
+               handle_t *handle = NULL;
+               int err, migrate = 0;
+               struct ext4_iloc iloc;
+-              unsigned int oldflags;
++              unsigned int oldflags, mask, i;
+               unsigned int jflag;
+               if (!inode_owner_or_capable(inode))
+@@ -115,8 +115,14 @@ long ext4_ioctl(struct file *filp, unsig
+               if (err)
+                       goto flags_err;
+-              flags = flags & EXT4_FL_USER_MODIFIABLE;
+-              flags |= oldflags & ~EXT4_FL_USER_MODIFIABLE;
++              for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
++                      if (!(mask & EXT4_FL_USER_MODIFIABLE))
++                              continue;
++                      if (mask & flags)
++                              ext4_set_inode_flag(inode, i);
++                      else
++                              ext4_clear_inode_flag(inode, i);
++              }
+               ei->i_flags = flags;
+               ext4_set_inode_flags(inode);
diff --git a/queue-3.4/ext4-fix-potential-integer-overflow-in-alloc_flex_gd.patch b/queue-3.4/ext4-fix-potential-integer-overflow-in-alloc_flex_gd.patch
new file mode 100644 (file)
index 0000000..6a7f8c9
--- /dev/null
@@ -0,0 +1,37 @@
+From 967ac8af4475ce45474800709b12137aa7634c77 Mon Sep 17 00:00:00 2001
+From: Haogang Chen <haogangchen@gmail.com>
+Date: Mon, 28 May 2012 14:21:55 -0400
+Subject: ext4: fix potential integer overflow in alloc_flex_gd()
+
+From: Haogang Chen <haogangchen@gmail.com>
+
+commit 967ac8af4475ce45474800709b12137aa7634c77 upstream.
+
+In alloc_flex_gd(), when flexbg_size is large, kmalloc size would
+overflow and flex_gd->groups would point to a buffer smaller than
+expected, causing OOB accesses when it is used.
+
+Note that in ext4_resize_fs(), flexbg_size is calculated using
+sbi->s_log_groups_per_flex, which is read from the disk and only bounded
+to [1, 31]. The patch returns NULL for too large flexbg_size.
+
+Reviewed-by: Eric Sandeen <sandeen@redhat.com>
+Signed-off-by: Haogang Chen <haogangchen@gmail.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -161,6 +161,8 @@ static struct ext4_new_flex_group_data *
+       if (flex_gd == NULL)
+               goto out3;
++      if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_flex_group_data))
++              goto out2;
+       flex_gd->count = flexbg_size;
+       flex_gd->groups = kmalloc(sizeof(struct ext4_new_group_data) *
diff --git a/queue-3.4/ext4-fix-potential-null-dereference-in-ext4_free_inodes_counts.patch b/queue-3.4/ext4-fix-potential-null-dereference-in-ext4_free_inodes_counts.patch
new file mode 100644 (file)
index 0000000..aad75da
--- /dev/null
@@ -0,0 +1,41 @@
+From bb3d132a24cd8bf5e7773b2d9f9baa58b07a7dae Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Mon, 28 May 2012 14:16:57 -0400
+Subject: ext4: fix potential NULL dereference in ext4_free_inodes_counts()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit bb3d132a24cd8bf5e7773b2d9f9baa58b07a7dae upstream.
+
+The ext4_get_group_desc() function returns NULL on error, and
+ext4_free_inodes_count() function dereferences it without checking.
+There is a check on the next line, but it's too late.
+
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ialloc.c |   10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -488,10 +488,12 @@ fallback_retry:
+       for (i = 0; i < ngroups; i++) {
+               grp = (parent_group + i) % ngroups;
+               desc = ext4_get_group_desc(sb, grp, NULL);
+-              grp_free = ext4_free_inodes_count(sb, desc);
+-              if (desc && grp_free && grp_free >= avefreei) {
+-                      *group = grp;
+-                      return 0;
++              if (desc) {
++                      grp_free = ext4_free_inodes_count(sb, desc);
++                      if (grp_free && grp_free >= avefreei) {
++                              *group = grp;
++                              return 0;
++                      }
+               }
+       }
diff --git a/queue-3.4/ext4-force-ro-mount-if-ext4_setup_super-fails.patch b/queue-3.4/ext4-force-ro-mount-if-ext4_setup_super-fails.patch
new file mode 100644 (file)
index 0000000..bd25672
--- /dev/null
@@ -0,0 +1,43 @@
+From 7e84b6216467b84cd332c8e567bf5aa113fd2f38 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@redhat.com>
+Date: Mon, 28 May 2012 14:17:25 -0400
+Subject: ext4: force ro mount if ext4_setup_super() fails
+
+From: Eric Sandeen <sandeen@redhat.com>
+
+commit 7e84b6216467b84cd332c8e567bf5aa113fd2f38 upstream.
+
+If ext4_setup_super() fails i.e. due to a too-high revision,
+the error is logged in dmesg but the fs is not mounted RO as
+indicated.
+
+Tested by:
+
+# mkfs.ext4 -r 4 /dev/sdb6
+# mount /dev/sdb6 /mnt/test
+# dmesg | grep "too high"
+[164919.759248] EXT4-fs (sdb6): revision level too high, forcing read-only mode
+# grep sdb6 /proc/mounts
+/dev/sdb6 /mnt/test2 ext4 rw,seclabel,relatime,data=ordered 0 0
+
+Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3592,7 +3592,8 @@ no_journal:
+               goto failed_mount4;
+       }
+-      ext4_setup_super(sb, es, sb->s_flags & MS_RDONLY);
++      if (ext4_setup_super(sb, es, sb->s_flags & MS_RDONLY))
++              sb->s_flags |= MS_RDONLY;
+       /* determine the minimum size of new large inodes, if present */
+       if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) {
diff --git a/queue-3.4/ext4-remove-mb_groups-before-tearing-down-the-buddy_cache.patch b/queue-3.4/ext4-remove-mb_groups-before-tearing-down-the-buddy_cache.patch
new file mode 100644 (file)
index 0000000..d67ca43
--- /dev/null
@@ -0,0 +1,50 @@
+From 95599968d19db175829fb580baa6b68939b320fb Mon Sep 17 00:00:00 2001
+From: Salman Qazi <sqazi@google.com>
+Date: Thu, 31 May 2012 23:52:14 -0400
+Subject: ext4: remove mb_groups before tearing down the buddy_cache
+
+From: Salman Qazi <sqazi@google.com>
+
+commit 95599968d19db175829fb580baa6b68939b320fb upstream.
+
+We can't have references held on pages in the s_buddy_cache while we are
+trying to truncate its pages and put the inode.  All the pages must be
+gone before we reach clear_inode.  This can only be gauranteed if we
+can prevent new users from grabbing references to s_buddy_cache's pages.
+
+The original bug can be reproduced and the bug fix can be verified by:
+
+while true; do mount -t ext4 /dev/ram0 /export/hda3/ram0; \
+       umount /export/hda3/ram0; done &
+
+while true; do cat /proc/fs/ext4/ram0/mb_groups; done
+
+Signed-off-by: Salman Qazi <sqazi@google.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/mballoc.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -2517,6 +2517,9 @@ int ext4_mb_release(struct super_block *
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct kmem_cache *cachep = get_groupinfo_cache(sb->s_blocksize_bits);
++      if (sbi->s_proc)
++              remove_proc_entry("mb_groups", sbi->s_proc);
++
+       if (sbi->s_group_info) {
+               for (i = 0; i < ngroups; i++) {
+                       grinfo = ext4_get_group_info(sb, i);
+@@ -2564,8 +2567,6 @@ int ext4_mb_release(struct super_block *
+       }
+       free_percpu(sbi->s_locality_groups);
+-      if (sbi->s_proc)
+-              remove_proc_entry("mb_groups", sbi->s_proc);
+       return 0;
+ }
index 56f12c68ce1bf37b6f4970ba7a3afdb69c03e10e..83cf8f1081d1dca9e829c86aa36145dee313fd77 100644 (file)
@@ -56,3 +56,11 @@ ipv6-fix-incorrect-ipsec-fragment.patch
 l2tp-fix-oops-in-l2tp-ip-sockets-for-connect-af_unspec-case.patch
 skb-avoid-unnecessary-reallocations-in-__skb_cow.patch
 xfrm-take-net-hdr-len-into-account-for-esp-payload-size-calculation.patch
+ext4-fix-potential-null-dereference-in-ext4_free_inodes_counts.patch
+ext4-force-ro-mount-if-ext4_setup_super-fails.patch
+ext4-fix-potential-integer-overflow-in-alloc_flex_gd.patch
+ext4-disallow-hard-linked-directory-in-ext4_lookup.patch
+ext4-add-missing-save_error_info-to-ext4_error.patch
+ext4-don-t-trash-state-flags-in-ext4_ioc_setflags.patch
+ext4-add-ext4_mb_unload_buddy-in-the-error-path.patch
+ext4-remove-mb_groups-before-tearing-down-the-buddy_cache.patch