]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Dec 2019 12:31:36 +0000 (13:31 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Dec 2019 12:31:36 +0000 (13:31 +0100)
added patches:
ext4-add-more-paranoia-checking-in-ext4_expand_extra_isize-handling.patch

queue-5.3/ext4-add-more-paranoia-checking-in-ext4_expand_extra_isize-handling.patch [new file with mode: 0644]
queue-5.3/series

diff --git a/queue-5.3/ext4-add-more-paranoia-checking-in-ext4_expand_extra_isize-handling.patch b/queue-5.3/ext4-add-more-paranoia-checking-in-ext4_expand_extra_isize-handling.patch
new file mode 100644 (file)
index 0000000..3da0201
--- /dev/null
@@ -0,0 +1,93 @@
+From 4ea99936a1630f51fc3a2d61a58ec4a1c4b7d55a Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 7 Nov 2019 21:43:41 -0500
+Subject: ext4: add more paranoia checking in ext4_expand_extra_isize handling
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 4ea99936a1630f51fc3a2d61a58ec4a1c4b7d55a upstream.
+
+It's possible to specify a non-zero s_want_extra_isize via debugging
+option, and this can cause bad things(tm) to happen when using a file
+system with an inode size of 128 bytes.
+
+Add better checking when the file system is mounted, as well as when
+we are actually doing the trying to do the inode expansion.
+
+Link: https://lore.kernel.org/r/20191110121510.GH23325@mit.edu
+Reported-by: syzbot+f8d6f8386ceacdbfff57@syzkaller.appspotmail.com
+Reported-by: syzbot+33d7ea72e47de3bdf4e1@syzkaller.appspotmail.com
+Reported-by: syzbot+44b6763edfc17144296f@syzkaller.appspotmail.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inode.c |   15 +++++++++++++++
+ fs/ext4/super.c |   21 ++++++++++++---------
+ 2 files changed, 27 insertions(+), 9 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -5942,8 +5942,23 @@ static int __ext4_expand_extra_isize(str
+ {
+       struct ext4_inode *raw_inode;
+       struct ext4_xattr_ibody_header *header;
++      unsigned int inode_size = EXT4_INODE_SIZE(inode->i_sb);
++      struct ext4_inode_info *ei = EXT4_I(inode);
+       int error;
++      /* this was checked at iget time, but double check for good measure */
++      if ((EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > inode_size) ||
++          (ei->i_extra_isize & 3)) {
++              EXT4_ERROR_INODE(inode, "bad extra_isize %u (inode size %u)",
++                               ei->i_extra_isize,
++                               EXT4_INODE_SIZE(inode->i_sb));
++              return -EFSCORRUPTED;
++      }
++      if ((new_extra_isize < ei->i_extra_isize) ||
++          (new_extra_isize < 4) ||
++          (new_extra_isize > inode_size - EXT4_GOOD_OLD_INODE_SIZE))
++              return -EINVAL; /* Should never happen */
++
+       raw_inode = ext4_raw_inode(iloc);
+       header = IHDR(inode, raw_inode);
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3544,12 +3544,15 @@ static void ext4_clamp_want_extra_isize(
+ {
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_super_block *es = sbi->s_es;
++      unsigned def_extra_isize = sizeof(struct ext4_inode) -
++                                              EXT4_GOOD_OLD_INODE_SIZE;
+-      /* determine the minimum size of new large inodes, if present */
+-      if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE &&
+-          sbi->s_want_extra_isize == 0) {
+-              sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
+-                                                   EXT4_GOOD_OLD_INODE_SIZE;
++      if (sbi->s_inode_size == EXT4_GOOD_OLD_INODE_SIZE) {
++              sbi->s_want_extra_isize = 0;
++              return;
++      }
++      if (sbi->s_want_extra_isize < 4) {
++              sbi->s_want_extra_isize = def_extra_isize;
+               if (ext4_has_feature_extra_isize(sb)) {
+                       if (sbi->s_want_extra_isize <
+                           le16_to_cpu(es->s_want_extra_isize))
+@@ -3562,10 +3565,10 @@ static void ext4_clamp_want_extra_isize(
+               }
+       }
+       /* Check if enough inode space is available */
+-      if (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize >
+-                                                      sbi->s_inode_size) {
+-              sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
+-                                                     EXT4_GOOD_OLD_INODE_SIZE;
++      if ((sbi->s_want_extra_isize > sbi->s_inode_size) ||
++          (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize >
++                                                      sbi->s_inode_size)) {
++              sbi->s_want_extra_isize = def_extra_isize;
+               ext4_msg(sb, KERN_INFO,
+                        "required extra inode space not available");
+       }
index 606aa2eded3dc08c464a1c2fcef3eff3c991feb5..a3a5f23cfe57b995d946099437f40494c3dc7f8a 100644 (file)
@@ -129,3 +129,4 @@ selftests-bpf-test_sockmap-handle-file-creation-failures-gracefully.patch
 selftests-bpf-correct-perror-strings.patch
 tipc-fix-link-name-length-check.patch
 selftests-pmtu-use-oneline-for-ip-route-list-cache.patch
+ext4-add-more-paranoia-checking-in-ext4_expand_extra_isize-handling.patch