]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.17-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Apr 2022 11:59:40 +0000 (13:59 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Apr 2022 11:59:40 +0000 (13:59 +0200)
added patches:
ext4-doc-fix-incorrect-h_reserved-size.patch
ext4-fix-fallocate-to-use-file_modified-to-update-permissions-consistently.patch
ext4-fix-overhead-calculation-to-account-for-the-reserved-gdt-blocks.patch
ext4-fix-symlink-file-size-not-match-to-file-content.patch
ext4-fix-use-after-free-in-ext4_search_dir.patch
ext4-force-overhead-calculation-if-the-s_overhead_cluster-makes-no-sense.patch
ext4-limit-length-to-bitmap_maxbytes-blocksize-in-punch_hole.patch
ext4-update-the-cached-overhead-value-in-the-superblock.patch

queue-5.17/ext4-doc-fix-incorrect-h_reserved-size.patch [new file with mode: 0644]
queue-5.17/ext4-fix-fallocate-to-use-file_modified-to-update-permissions-consistently.patch [new file with mode: 0644]
queue-5.17/ext4-fix-overhead-calculation-to-account-for-the-reserved-gdt-blocks.patch [new file with mode: 0644]
queue-5.17/ext4-fix-symlink-file-size-not-match-to-file-content.patch [new file with mode: 0644]
queue-5.17/ext4-fix-use-after-free-in-ext4_search_dir.patch [new file with mode: 0644]
queue-5.17/ext4-force-overhead-calculation-if-the-s_overhead_cluster-makes-no-sense.patch [new file with mode: 0644]
queue-5.17/ext4-limit-length-to-bitmap_maxbytes-blocksize-in-punch_hole.patch [new file with mode: 0644]
queue-5.17/ext4-update-the-cached-overhead-value-in-the-superblock.patch [new file with mode: 0644]
queue-5.17/series

diff --git a/queue-5.17/ext4-doc-fix-incorrect-h_reserved-size.patch b/queue-5.17/ext4-doc-fix-incorrect-h_reserved-size.patch
new file mode 100644 (file)
index 0000000..5755583
--- /dev/null
@@ -0,0 +1,32 @@
+From 7102ffe4c166ca0f5e35137e9f9de83768c2d27d Mon Sep 17 00:00:00 2001
+From: "wangjianjian (C)" <wangjianjian3@huawei.com>
+Date: Fri, 1 Apr 2022 20:07:35 +0800
+Subject: ext4, doc: fix incorrect h_reserved size
+
+From: wangjianjian (C) <wangjianjian3@huawei.com>
+
+commit 7102ffe4c166ca0f5e35137e9f9de83768c2d27d upstream.
+
+According to document and code, ext4_xattr_header's size is 32 bytes, so
+h_reserved size should be 3.
+
+Signed-off-by: Wang Jianjian <wangjianjian3@huawei.com>
+Link: https://lore.kernel.org/r/92fcc3a6-7d77-8c09-4126-377fcb4c46a5@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/filesystems/ext4/attributes.rst |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/Documentation/filesystems/ext4/attributes.rst
++++ b/Documentation/filesystems/ext4/attributes.rst
+@@ -76,7 +76,7 @@ The beginning of an extended attribute b
+      - Checksum of the extended attribute block.
+    * - 0x14
+      - \_\_u32
+-     - h\_reserved[2]
++     - h\_reserved[3]
+      - Zero.
+ The checksum is calculated against the FS UUID, the 64-bit block number
diff --git a/queue-5.17/ext4-fix-fallocate-to-use-file_modified-to-update-permissions-consistently.patch b/queue-5.17/ext4-fix-fallocate-to-use-file_modified-to-update-permissions-consistently.patch
new file mode 100644 (file)
index 0000000..0dea205
--- /dev/null
@@ -0,0 +1,170 @@
+From ad5cd4f4ee4d5fcdb1bfb7a0c073072961e70783 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Tue, 8 Mar 2022 10:50:43 -0800
+Subject: ext4: fix fallocate to use file_modified to update permissions consistently
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit ad5cd4f4ee4d5fcdb1bfb7a0c073072961e70783 upstream.
+
+Since the initial introduction of (posix) fallocate back at the turn of
+the century, it has been possible to use this syscall to change the
+user-visible contents of files.  This can happen by extending the file
+size during a preallocation, or through any of the newer modes (punch,
+zero, collapse, insert range).  Because the call can be used to change
+file contents, we should treat it like we do any other modification to a
+file -- update the mtime, and drop set[ug]id privileges/capabilities.
+
+The VFS function file_modified() does all this for us if pass it a
+locked inode, so let's make fallocate drop permissions correctly.
+
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Link: https://lore.kernel.org/r/20220308185043.GA117678@magnolia
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ext4.h    |    2 +-
+ fs/ext4/extents.c |   32 +++++++++++++++++++++++++-------
+ fs/ext4/inode.c   |    7 ++++++-
+ 3 files changed, 32 insertions(+), 9 deletions(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -3030,7 +3030,7 @@ extern int ext4_inode_attach_jinode(stru
+ extern int ext4_can_truncate(struct inode *inode);
+ extern int ext4_truncate(struct inode *);
+ extern int ext4_break_layouts(struct inode *);
+-extern int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length);
++extern int ext4_punch_hole(struct file *file, loff_t offset, loff_t length);
+ extern void ext4_set_inode_flags(struct inode *, bool init);
+ extern int ext4_alloc_da_blocks(struct inode *inode);
+ extern void ext4_set_aops(struct inode *inode);
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -4501,9 +4501,9 @@ retry:
+       return ret > 0 ? ret2 : ret;
+ }
+-static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len);
++static int ext4_collapse_range(struct file *file, loff_t offset, loff_t len);
+-static int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len);
++static int ext4_insert_range(struct file *file, loff_t offset, loff_t len);
+ static long ext4_zero_range(struct file *file, loff_t offset,
+                           loff_t len, int mode)
+@@ -4575,6 +4575,10 @@ static long ext4_zero_range(struct file
+       /* Wait all existing dio workers, newcomers will block on i_rwsem */
+       inode_dio_wait(inode);
++      ret = file_modified(file);
++      if (ret)
++              goto out_mutex;
++
+       /* Preallocate the range including the unaligned edges */
+       if (partial_begin || partial_end) {
+               ret = ext4_alloc_file_blocks(file,
+@@ -4691,7 +4695,7 @@ long ext4_fallocate(struct file *file, i
+               return -EOPNOTSUPP;
+       if (mode & FALLOC_FL_PUNCH_HOLE) {
+-              ret = ext4_punch_hole(inode, offset, len);
++              ret = ext4_punch_hole(file, offset, len);
+               goto exit;
+       }
+@@ -4700,12 +4704,12 @@ long ext4_fallocate(struct file *file, i
+               goto exit;
+       if (mode & FALLOC_FL_COLLAPSE_RANGE) {
+-              ret = ext4_collapse_range(inode, offset, len);
++              ret = ext4_collapse_range(file, offset, len);
+               goto exit;
+       }
+       if (mode & FALLOC_FL_INSERT_RANGE) {
+-              ret = ext4_insert_range(inode, offset, len);
++              ret = ext4_insert_range(file, offset, len);
+               goto exit;
+       }
+@@ -4741,6 +4745,10 @@ long ext4_fallocate(struct file *file, i
+       /* Wait all existing dio workers, newcomers will block on i_rwsem */
+       inode_dio_wait(inode);
++      ret = file_modified(file);
++      if (ret)
++              goto out;
++
+       ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, flags);
+       if (ret)
+               goto out;
+@@ -5242,8 +5250,9 @@ out:
+  * This implements the fallocate's collapse range functionality for ext4
+  * Returns: 0 and non-zero on error.
+  */
+-static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
++static int ext4_collapse_range(struct file *file, loff_t offset, loff_t len)
+ {
++      struct inode *inode = file_inode(file);
+       struct super_block *sb = inode->i_sb;
+       struct address_space *mapping = inode->i_mapping;
+       ext4_lblk_t punch_start, punch_stop;
+@@ -5295,6 +5304,10 @@ static int ext4_collapse_range(struct in
+       /* Wait for existing dio to complete */
+       inode_dio_wait(inode);
++      ret = file_modified(file);
++      if (ret)
++              goto out_mutex;
++
+       /*
+        * Prevent page faults from reinstantiating pages we have released from
+        * page cache.
+@@ -5388,8 +5401,9 @@ out_mutex:
+  * by len bytes.
+  * Returns 0 on success, error otherwise.
+  */
+-static int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len)
++static int ext4_insert_range(struct file *file, loff_t offset, loff_t len)
+ {
++      struct inode *inode = file_inode(file);
+       struct super_block *sb = inode->i_sb;
+       struct address_space *mapping = inode->i_mapping;
+       handle_t *handle;
+@@ -5446,6 +5460,10 @@ static int ext4_insert_range(struct inod
+       /* Wait for existing dio to complete */
+       inode_dio_wait(inode);
++      ret = file_modified(file);
++      if (ret)
++              goto out_mutex;
++
+       /*
+        * Prevent page faults from reinstantiating pages we have released from
+        * page cache.
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -3944,8 +3944,9 @@ int ext4_break_layouts(struct inode *ino
+  * Returns: 0 on success or negative on failure
+  */
+-int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
++int ext4_punch_hole(struct file *file, loff_t offset, loff_t length)
+ {
++      struct inode *inode = file_inode(file);
+       struct super_block *sb = inode->i_sb;
+       ext4_lblk_t first_block, stop_block;
+       struct address_space *mapping = inode->i_mapping;
+@@ -4007,6 +4008,10 @@ int ext4_punch_hole(struct inode *inode,
+       /* Wait all existing dio workers, newcomers will block on i_rwsem */
+       inode_dio_wait(inode);
++      ret = file_modified(file);
++      if (ret)
++              goto out_mutex;
++
+       /*
+        * Prevent page faults from reinstantiating pages we have released from
+        * page cache.
diff --git a/queue-5.17/ext4-fix-overhead-calculation-to-account-for-the-reserved-gdt-blocks.patch b/queue-5.17/ext4-fix-overhead-calculation-to-account-for-the-reserved-gdt-blocks.patch
new file mode 100644 (file)
index 0000000..488b056
--- /dev/null
@@ -0,0 +1,35 @@
+From 10b01ee92df52c8d7200afead4d5e5f55a5c58b1 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 14 Apr 2022 21:31:27 -0400
+Subject: ext4: fix overhead calculation to account for the reserved gdt blocks
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 10b01ee92df52c8d7200afead4d5e5f55a5c58b1 upstream.
+
+The kernel calculation was underestimating the overhead by not taking
+into account the reserved gdt blocks.  With this change, the overhead
+calculated by the kernel matches the overhead calculation in mke2fs.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/super.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -4156,9 +4156,11 @@ static int count_overhead(struct super_b
+       ext4_fsblk_t            first_block, last_block, b;
+       ext4_group_t            i, ngroups = ext4_get_groups_count(sb);
+       int                     s, j, count = 0;
++      int                     has_super = ext4_bg_has_super(sb, grp);
+       if (!ext4_has_feature_bigalloc(sb))
+-              return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) +
++              return (has_super + ext4_bg_num_gdb(sb, grp) +
++                      (has_super ? le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) : 0) +
+                       sbi->s_itb_per_group + 2);
+       first_block = le32_to_cpu(sbi->s_es->s_first_data_block) +
diff --git a/queue-5.17/ext4-fix-symlink-file-size-not-match-to-file-content.patch b/queue-5.17/ext4-fix-symlink-file-size-not-match-to-file-content.patch
new file mode 100644 (file)
index 0000000..7e0fad2
--- /dev/null
@@ -0,0 +1,51 @@
+From a2b0b205d125f27cddfb4f7280e39affdaf46686 Mon Sep 17 00:00:00 2001
+From: Ye Bin <yebin10@huawei.com>
+Date: Mon, 21 Mar 2022 22:44:38 +0800
+Subject: ext4: fix symlink file size not match to file content
+
+From: Ye Bin <yebin10@huawei.com>
+
+commit a2b0b205d125f27cddfb4f7280e39affdaf46686 upstream.
+
+We got issue as follows:
+[home]# fsck.ext4  -fn  ram0yb
+e2fsck 1.45.6 (20-Mar-2020)
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Symlink /p3/d14/d1a/l3d (inode #3494) is invalid.
+Clear? no
+Entry 'l3d' in /p3/d14/d1a (3383) has an incorrect filetype (was 7, should be 0).
+Fix? no
+
+As the symlink file size does not match the file content. If the writeback
+of the symlink data block failed, ext4_finish_bio() handles the end of IO.
+However this function fails to mark the buffer with BH_write_io_error and
+so when unmount does journal checkpoint it cannot detect the writeback
+error and will cleanup the journal. Thus we've lost the correct data in the
+journal area. To solve this issue, mark the buffer as BH_write_io_error in
+ext4_finish_bio().
+
+Cc: stable@kernel.org
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20220321144438.201685-1-yebin10@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/page-io.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/page-io.c
++++ b/fs/ext4/page-io.c
+@@ -134,8 +134,10 @@ static void ext4_finish_bio(struct bio *
+                               continue;
+                       }
+                       clear_buffer_async_write(bh);
+-                      if (bio->bi_status)
++                      if (bio->bi_status) {
++                              set_buffer_write_io_error(bh);
+                               buffer_io_error(bh);
++                      }
+               } while ((bh = bh->b_this_page) != head);
+               spin_unlock_irqrestore(&head->b_uptodate_lock, flags);
+               if (!under_io) {
diff --git a/queue-5.17/ext4-fix-use-after-free-in-ext4_search_dir.patch b/queue-5.17/ext4-fix-use-after-free-in-ext4_search_dir.patch
new file mode 100644 (file)
index 0000000..157347b
--- /dev/null
@@ -0,0 +1,125 @@
+From c186f0887fe7061a35cebef024550ec33ef8fbd8 Mon Sep 17 00:00:00 2001
+From: Ye Bin <yebin10@huawei.com>
+Date: Thu, 24 Mar 2022 14:48:16 +0800
+Subject: ext4: fix use-after-free in ext4_search_dir
+
+From: Ye Bin <yebin10@huawei.com>
+
+commit c186f0887fe7061a35cebef024550ec33ef8fbd8 upstream.
+
+We got issue as follows:
+EXT4-fs (loop0): mounted filesystem without journal. Opts: ,errors=continue
+==================================================================
+BUG: KASAN: use-after-free in ext4_search_dir fs/ext4/namei.c:1394 [inline]
+BUG: KASAN: use-after-free in search_dirblock fs/ext4/namei.c:1199 [inline]
+BUG: KASAN: use-after-free in __ext4_find_entry+0xdca/0x1210 fs/ext4/namei.c:1553
+Read of size 1 at addr ffff8881317c3005 by task syz-executor117/2331
+
+CPU: 1 PID: 2331 Comm: syz-executor117 Not tainted 5.10.0+ #1
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
+Call Trace:
+ __dump_stack lib/dump_stack.c:83 [inline]
+ dump_stack+0x144/0x187 lib/dump_stack.c:124
+ print_address_description+0x7d/0x630 mm/kasan/report.c:387
+ __kasan_report+0x132/0x190 mm/kasan/report.c:547
+ kasan_report+0x47/0x60 mm/kasan/report.c:564
+ ext4_search_dir fs/ext4/namei.c:1394 [inline]
+ search_dirblock fs/ext4/namei.c:1199 [inline]
+ __ext4_find_entry+0xdca/0x1210 fs/ext4/namei.c:1553
+ ext4_lookup_entry fs/ext4/namei.c:1622 [inline]
+ ext4_lookup+0xb8/0x3a0 fs/ext4/namei.c:1690
+ __lookup_hash+0xc5/0x190 fs/namei.c:1451
+ do_rmdir+0x19e/0x310 fs/namei.c:3760
+ do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+RIP: 0033:0x445e59
+Code: 4d c7 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 1b c7 fb ff c3 66 2e 0f 1f 84 00 00 00 00
+RSP: 002b:00007fff2277fac8 EFLAGS: 00000246 ORIG_RAX: 0000000000000054
+RAX: ffffffffffffffda RBX: 0000000000400280 RCX: 0000000000445e59
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00000000200000c0
+RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000002
+R10: 00007fff2277f990 R11: 0000000000000246 R12: 0000000000000000
+R13: 431bde82d7b634db R14: 0000000000000000 R15: 0000000000000000
+
+The buggy address belongs to the page:
+page:0000000048cd3304 refcount:0 mapcount:0 mapping:0000000000000000 index:0x1 pfn:0x1317c3
+flags: 0x200000000000000()
+raw: 0200000000000000 ffffea0004526588 ffffea0004528088 0000000000000000
+raw: 0000000000000001 0000000000000000 00000000ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffff8881317c2f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ ffff8881317c2f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+>ffff8881317c3000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+                   ^
+ ffff8881317c3080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+ ffff8881317c3100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+==================================================================
+
+ext4_search_dir:
+  ...
+  de = (struct ext4_dir_entry_2 *)search_buf;
+  dlimit = search_buf + buf_size;
+  while ((char *) de < dlimit) {
+  ...
+    if ((char *) de + de->name_len <= dlimit &&
+        ext4_match(dir, fname, de)) {
+           ...
+    }
+  ...
+    de_len = ext4_rec_len_from_disk(de->rec_len, dir->i_sb->s_blocksize);
+    if (de_len <= 0)
+      return -1;
+    offset += de_len;
+    de = (struct ext4_dir_entry_2 *) ((char *) de + de_len);
+  }
+
+Assume:
+de=0xffff8881317c2fff
+dlimit=0x0xffff8881317c3000
+
+If read 'de->name_len' which address is 0xffff8881317c3005, obviously is
+out of range, then will trigger use-after-free.
+To solve this issue, 'dlimit' must reserve 8 bytes, as we will read
+'de->name_len' to judge if '(char *) de + de->name_len' out of range.
+
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20220324064816.1209985-1-yebin10@huawei.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/ext4.h  |    4 ++++
+ fs/ext4/namei.c |    4 ++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2271,6 +2271,10 @@ static inline int ext4_forced_shutdown(s
+  * Structure of a directory entry
+  */
+ #define EXT4_NAME_LEN 255
++/*
++ * Base length of the ext4 directory entry excluding the name length
++ */
++#define EXT4_BASE_DIR_LEN (sizeof(struct ext4_dir_entry_2) - EXT4_NAME_LEN)
+ struct ext4_dir_entry {
+       __le32  inode;                  /* Inode number */
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1466,10 +1466,10 @@ int ext4_search_dir(struct buffer_head *
+       de = (struct ext4_dir_entry_2 *)search_buf;
+       dlimit = search_buf + buf_size;
+-      while ((char *) de < dlimit) {
++      while ((char *) de < dlimit - EXT4_BASE_DIR_LEN) {
+               /* this code is executed quadratically often */
+               /* do minimal checking `by hand' */
+-              if ((char *) de + de->name_len <= dlimit &&
++              if (de->name + de->name_len <= dlimit &&
+                   ext4_match(dir, fname, de)) {
+                       /* found a match - just to be sure, do
+                        * a full check */
diff --git a/queue-5.17/ext4-force-overhead-calculation-if-the-s_overhead_cluster-makes-no-sense.patch b/queue-5.17/ext4-force-overhead-calculation-if-the-s_overhead_cluster-makes-no-sense.patch
new file mode 100644 (file)
index 0000000..5ae8fdf
--- /dev/null
@@ -0,0 +1,44 @@
+From 85d825dbf4899a69407338bae462a59aa9a37326 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 14 Apr 2022 21:57:49 -0400
+Subject: ext4: force overhead calculation if the s_overhead_cluster makes no sense
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 85d825dbf4899a69407338bae462a59aa9a37326 upstream.
+
+If the file system does not use bigalloc, calculating the overhead is
+cheap, so force the recalculation of the overhead so we don't have to
+trust the precalculated overhead in the superblock.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/super.c |   15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5268,9 +5268,18 @@ no_journal:
+        * Get the # of file system overhead blocks from the
+        * superblock if present.
+        */
+-      if (es->s_overhead_clusters)
+-              sbi->s_overhead = le32_to_cpu(es->s_overhead_clusters);
+-      else {
++      sbi->s_overhead = le32_to_cpu(es->s_overhead_clusters);
++      /* ignore the precalculated value if it is ridiculous */
++      if (sbi->s_overhead > ext4_blocks_count(es))
++              sbi->s_overhead = 0;
++      /*
++       * If the bigalloc feature is not enabled recalculating the
++       * overhead doesn't take long, so we might as well just redo
++       * it to make sure we are using the correct value.
++       */
++      if (!ext4_has_feature_bigalloc(sb))
++              sbi->s_overhead = 0;
++      if (sbi->s_overhead == 0) {
+               err = ext4_calculate_overhead(sb);
+               if (err)
+                       goto failed_mount_wq;
diff --git a/queue-5.17/ext4-limit-length-to-bitmap_maxbytes-blocksize-in-punch_hole.patch b/queue-5.17/ext4-limit-length-to-bitmap_maxbytes-blocksize-in-punch_hole.patch
new file mode 100644 (file)
index 0000000..7abc892
--- /dev/null
@@ -0,0 +1,60 @@
+From 2da376228a2427501feb9d15815a45dbdbdd753e Mon Sep 17 00:00:00 2001
+From: Tadeusz Struk <tadeusz.struk@linaro.org>
+Date: Thu, 31 Mar 2022 13:05:15 -0700
+Subject: ext4: limit length to bitmap_maxbytes - blocksize in punch_hole
+
+From: Tadeusz Struk <tadeusz.struk@linaro.org>
+
+commit 2da376228a2427501feb9d15815a45dbdbdd753e upstream.
+
+Syzbot found an issue [1] in ext4_fallocate().
+The C reproducer [2] calls fallocate(), passing size 0xffeffeff000ul,
+and offset 0x1000000ul, which, when added together exceed the
+bitmap_maxbytes for the inode. This triggers a BUG in
+ext4_ind_remove_space(). According to the comments in this function
+the 'end' parameter needs to be one block after the last block to be
+removed. In the case when the BUG is triggered it points to the last
+block. Modify the ext4_punch_hole() function and add constraint that
+caps the length to satisfy the one before laster block requirement.
+
+LINK: [1] https://syzkaller.appspot.com/bug?id=b80bd9cf348aac724a4f4dff251800106d721331
+LINK: [2] https://syzkaller.appspot.com/text?tag=ReproC&x=14ba0238700000
+
+Fixes: a4bb6b64e39a ("ext4: enable "punch hole" functionality")
+Reported-by: syzbot+7a806094edd5d07ba029@syzkaller.appspotmail.com
+Signed-off-by: Tadeusz Struk <tadeusz.struk@linaro.org>
+Link: https://lore.kernel.org/r/20220331200515.153214-1-tadeusz.struk@linaro.org
+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 |   11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -3950,7 +3950,8 @@ int ext4_punch_hole(struct file *file, l
+       struct super_block *sb = inode->i_sb;
+       ext4_lblk_t first_block, stop_block;
+       struct address_space *mapping = inode->i_mapping;
+-      loff_t first_block_offset, last_block_offset;
++      loff_t first_block_offset, last_block_offset, max_length;
++      struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+       handle_t *handle;
+       unsigned int credits;
+       int ret = 0, ret2 = 0;
+@@ -3993,6 +3994,14 @@ int ext4_punch_hole(struct file *file, l
+                  offset;
+       }
++      /*
++       * For punch hole the length + offset needs to be within one block
++       * before last range. Adjust the length if it goes beyond that limit.
++       */
++      max_length = sbi->s_bitmap_maxbytes - inode->i_sb->s_blocksize;
++      if (offset + length > max_length)
++              length = max_length - offset;
++
+       if (offset & (sb->s_blocksize - 1) ||
+           (offset + length) & (sb->s_blocksize - 1)) {
+               /*
diff --git a/queue-5.17/ext4-update-the-cached-overhead-value-in-the-superblock.patch b/queue-5.17/ext4-update-the-cached-overhead-value-in-the-superblock.patch
new file mode 100644 (file)
index 0000000..4a4f25f
--- /dev/null
@@ -0,0 +1,66 @@
+From eb7054212eac8b451d727bf079eae3db8c88f9d3 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 14 Apr 2022 22:39:00 -0400
+Subject: ext4: update the cached overhead value in the superblock
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit eb7054212eac8b451d727bf079eae3db8c88f9d3 upstream.
+
+If we (re-)calculate the file system overhead amount and it's
+different from the on-disk s_overhead_clusters value, update the
+on-disk version since this can take potentially quite a while on
+bigalloc file systems.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ext4.h  |    1 +
+ fs/ext4/ioctl.c |   16 ++++++++++++++++
+ fs/ext4/super.c |    2 ++
+ 3 files changed, 19 insertions(+)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -3066,6 +3066,7 @@ int ext4_fileattr_set(struct user_namesp
+                     struct dentry *dentry, struct fileattr *fa);
+ int ext4_fileattr_get(struct dentry *dentry, struct fileattr *fa);
+ extern void ext4_reset_inode_seed(struct inode *inode);
++int ext4_update_overhead(struct super_block *sb);
+ /* migrate.c */
+ extern int ext4_ext_migrate(struct inode *);
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -1652,3 +1652,19 @@ long ext4_compat_ioctl(struct file *file
+       return ext4_ioctl(file, cmd, (unsigned long) compat_ptr(arg));
+ }
+ #endif
++
++static void set_overhead(struct ext4_super_block *es, const void *arg)
++{
++      es->s_overhead_clusters = cpu_to_le32(*((unsigned long *) arg));
++}
++
++int ext4_update_overhead(struct super_block *sb)
++{
++      struct ext4_sb_info *sbi = EXT4_SB(sb);
++
++      if (sb_rdonly(sb) || sbi->s_overhead == 0 ||
++          sbi->s_overhead == le32_to_cpu(sbi->s_es->s_overhead_clusters))
++              return 0;
++
++      return ext4_update_superblocks_fn(sb, set_overhead, &sbi->s_overhead);
++}
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5597,6 +5597,8 @@ static int ext4_fill_super(struct super_
+               ext4_msg(sb, KERN_INFO, "mounted filesystem with%s. "
+                        "Quota mode: %s.", descr, ext4_quota_mode(sb));
++      /* Update the s_overhead_clusters if necessary */
++      ext4_update_overhead(sb);
+       return 0;
+ free_sbi:
index 2f0ec609280004fc3560e2d4f5375343e0e3bb46..f320eff02b63f8fbb81a11ae88895a71720a3107 100644 (file)
@@ -131,3 +131,11 @@ kvm-x86-pend-kvm_req_apicv_update-during-vcpu-creation-to-fix-a-race.patch
 kvm-nvmx-defer-apicv-updates-while-l2-is-active-until-l1-is-active.patch
 kvm-svm-simplify-and-harden-helper-to-flush-sev-guest-page-s.patch
 kvm-svm-flush-when-freeing-encrypted-pages-even-on-sme_coherent-cpus.patch
+ext4-fix-fallocate-to-use-file_modified-to-update-permissions-consistently.patch
+ext4-fix-symlink-file-size-not-match-to-file-content.patch
+ext4-fix-use-after-free-in-ext4_search_dir.patch
+ext4-limit-length-to-bitmap_maxbytes-blocksize-in-punch_hole.patch
+ext4-doc-fix-incorrect-h_reserved-size.patch
+ext4-fix-overhead-calculation-to-account-for-the-reserved-gdt-blocks.patch
+ext4-force-overhead-calculation-if-the-s_overhead_cluster-makes-no-sense.patch
+ext4-update-the-cached-overhead-value-in-the-superblock.patch