]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 7 Aug 2023 09:08:41 +0000 (11:08 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 7 Aug 2023 09:08:41 +0000 (11:08 +0200)
added patches:
btrfs-remove-bug_on-s-in-add_new_free_space.patch
ext2-drop-fragment-support.patch
f2fs-fix-to-do-sanity-check-on-direct-node-in-truncate_dnode.patch
fs-protect-reconfiguration-of-sb-read-write-from-racing-writes.patch
io_uring-annotate-offset-timeout-races.patch
net-usbnet-fix-warning-in-usbnet_start_xmit-usb_submit_urb.patch

queue-6.1/btrfs-remove-bug_on-s-in-add_new_free_space.patch [new file with mode: 0644]
queue-6.1/ext2-drop-fragment-support.patch [new file with mode: 0644]
queue-6.1/f2fs-fix-to-do-sanity-check-on-direct-node-in-truncate_dnode.patch [new file with mode: 0644]
queue-6.1/fs-protect-reconfiguration-of-sb-read-write-from-racing-writes.patch [new file with mode: 0644]
queue-6.1/io_uring-annotate-offset-timeout-races.patch [new file with mode: 0644]
queue-6.1/net-usbnet-fix-warning-in-usbnet_start_xmit-usb_submit_urb.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/btrfs-remove-bug_on-s-in-add_new_free_space.patch b/queue-6.1/btrfs-remove-bug_on-s-in-add_new_free_space.patch
new file mode 100644 (file)
index 0000000..a56bbc1
--- /dev/null
@@ -0,0 +1,214 @@
+From d8ccbd21918fd7fa6ce3226cffc22c444228e8ad Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Fri, 30 Jun 2023 16:03:44 +0100
+Subject: btrfs: remove BUG_ON()'s in add_new_free_space()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit d8ccbd21918fd7fa6ce3226cffc22c444228e8ad upstream.
+
+At add_new_free_space() we have these BUG_ON()'s that are there to deal
+with any failure to add free space to the in memory free space cache.
+Such failures are mostly -ENOMEM that should be very rare. However there's
+no need to have these BUG_ON()'s, we can just return any error to the
+caller and all callers and their upper call chain are already dealing with
+errors.
+
+So just make add_new_free_space() return any errors, while removing the
+BUG_ON()'s, and returning the total amount of added free space to an
+optional u64 pointer argument.
+
+Reported-by: syzbot+3ba856e07b7127889d8c@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/linux-btrfs/000000000000e9cb8305ff4e8327@google.com/
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/block-group.c     |   51 ++++++++++++++++++++++++++++++---------------
+ fs/btrfs/block-group.h     |    4 +--
+ fs/btrfs/free-space-tree.c |   24 +++++++++++++++------
+ 3 files changed, 53 insertions(+), 26 deletions(-)
+
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -494,12 +494,16 @@ static void fragment_free_space(struct b
+  * used yet since their free space will be released as soon as the transaction
+  * commits.
+  */
+-u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end)
++int add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end,
++                     u64 *total_added_ret)
+ {
+       struct btrfs_fs_info *info = block_group->fs_info;
+-      u64 extent_start, extent_end, size, total_added = 0;
++      u64 extent_start, extent_end, size;
+       int ret;
++      if (total_added_ret)
++              *total_added_ret = 0;
++
+       while (start < end) {
+               ret = find_first_extent_bit(&info->excluded_extents, start,
+                                           &extent_start, &extent_end,
+@@ -512,10 +516,12 @@ u64 add_new_free_space(struct btrfs_bloc
+                       start = extent_end + 1;
+               } else if (extent_start > start && extent_start < end) {
+                       size = extent_start - start;
+-                      total_added += size;
+                       ret = btrfs_add_free_space_async_trimmed(block_group,
+                                                                start, size);
+-                      BUG_ON(ret); /* -ENOMEM or logic error */
++                      if (ret)
++                              return ret;
++                      if (total_added_ret)
++                              *total_added_ret += size;
+                       start = extent_end + 1;
+               } else {
+                       break;
+@@ -524,13 +530,15 @@ u64 add_new_free_space(struct btrfs_bloc
+       if (start < end) {
+               size = end - start;
+-              total_added += size;
+               ret = btrfs_add_free_space_async_trimmed(block_group, start,
+                                                        size);
+-              BUG_ON(ret); /* -ENOMEM or logic error */
++              if (ret)
++                      return ret;
++              if (total_added_ret)
++                      *total_added_ret += size;
+       }
+-      return total_added;
++      return 0;
+ }
+ static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl)
+@@ -637,8 +645,13 @@ next:
+               if (key.type == BTRFS_EXTENT_ITEM_KEY ||
+                   key.type == BTRFS_METADATA_ITEM_KEY) {
+-                      total_found += add_new_free_space(block_group, last,
+-                                                        key.objectid);
++                      u64 space_added;
++
++                      ret = add_new_free_space(block_group, last, key.objectid,
++                                               &space_added);
++                      if (ret)
++                              goto out;
++                      total_found += space_added;
+                       if (key.type == BTRFS_METADATA_ITEM_KEY)
+                               last = key.objectid +
+                                       fs_info->nodesize;
+@@ -653,11 +666,10 @@ next:
+               }
+               path->slots[0]++;
+       }
+-      ret = 0;
+-
+-      total_found += add_new_free_space(block_group, last,
+-                              block_group->start + block_group->length);
++      ret = add_new_free_space(block_group, last,
++                               block_group->start + block_group->length,
++                               NULL);
+ out:
+       btrfs_free_path(path);
+       return ret;
+@@ -2101,9 +2113,11 @@ static int read_one_block_group(struct b
+               btrfs_free_excluded_extents(cache);
+       } else if (cache->used == 0) {
+               cache->cached = BTRFS_CACHE_FINISHED;
+-              add_new_free_space(cache, cache->start,
+-                                 cache->start + cache->length);
++              ret = add_new_free_space(cache, cache->start,
++                                       cache->start + cache->length, NULL);
+               btrfs_free_excluded_extents(cache);
++              if (ret)
++                      goto error;
+       }
+       ret = btrfs_add_block_group_cache(info, cache);
+@@ -2529,9 +2543,12 @@ struct btrfs_block_group *btrfs_make_blo
+               return ERR_PTR(ret);
+       }
+-      add_new_free_space(cache, chunk_offset, chunk_offset + size);
+-
++      ret = add_new_free_space(cache, chunk_offset, chunk_offset + size, NULL);
+       btrfs_free_excluded_extents(cache);
++      if (ret) {
++              btrfs_put_block_group(cache);
++              return ERR_PTR(ret);
++      }
+       /*
+        * Ensure the corresponding space_info object is created and
+--- a/fs/btrfs/block-group.h
++++ b/fs/btrfs/block-group.h
+@@ -284,8 +284,8 @@ int btrfs_cache_block_group(struct btrfs
+ void btrfs_put_caching_control(struct btrfs_caching_control *ctl);
+ struct btrfs_caching_control *btrfs_get_caching_control(
+               struct btrfs_block_group *cache);
+-u64 add_new_free_space(struct btrfs_block_group *block_group,
+-                     u64 start, u64 end);
++int add_new_free_space(struct btrfs_block_group *block_group,
++                     u64 start, u64 end, u64 *total_added_ret);
+ struct btrfs_trans_handle *btrfs_start_trans_remove_block_group(
+                               struct btrfs_fs_info *fs_info,
+                               const u64 chunk_offset);
+--- a/fs/btrfs/free-space-tree.c
++++ b/fs/btrfs/free-space-tree.c
+@@ -1510,9 +1510,13 @@ static int load_free_space_bitmaps(struc
+                       if (prev_bit == 0 && bit == 1) {
+                               extent_start = offset;
+                       } else if (prev_bit == 1 && bit == 0) {
+-                              total_found += add_new_free_space(block_group,
+-                                                                extent_start,
+-                                                                offset);
++                              u64 space_added;
++
++                              ret = add_new_free_space(block_group, extent_start,
++                                                       offset, &space_added);
++                              if (ret)
++                                      goto out;
++                              total_found += space_added;
+                               if (total_found > CACHING_CTL_WAKE_UP) {
+                                       total_found = 0;
+                                       wake_up(&caching_ctl->wait);
+@@ -1524,8 +1528,9 @@ static int load_free_space_bitmaps(struc
+               }
+       }
+       if (prev_bit == 1) {
+-              total_found += add_new_free_space(block_group, extent_start,
+-                                                end);
++              ret = add_new_free_space(block_group, extent_start, end, NULL);
++              if (ret)
++                      goto out;
+               extent_count++;
+       }
+@@ -1564,6 +1569,8 @@ static int load_free_space_extents(struc
+       end = block_group->start + block_group->length;
+       while (1) {
++              u64 space_added;
++
+               ret = btrfs_next_item(root, path);
+               if (ret < 0)
+                       goto out;
+@@ -1578,8 +1585,11 @@ static int load_free_space_extents(struc
+               ASSERT(key.type == BTRFS_FREE_SPACE_EXTENT_KEY);
+               ASSERT(key.objectid < end && key.objectid + key.offset <= end);
+-              total_found += add_new_free_space(block_group, key.objectid,
+-                                                key.objectid + key.offset);
++              ret = add_new_free_space(block_group, key.objectid,
++                                       key.objectid + key.offset, &space_added);
++              if (ret)
++                      goto out;
++              total_found += space_added;
+               if (total_found > CACHING_CTL_WAKE_UP) {
+                       total_found = 0;
+                       wake_up(&caching_ctl->wait);
diff --git a/queue-6.1/ext2-drop-fragment-support.patch b/queue-6.1/ext2-drop-fragment-support.patch
new file mode 100644 (file)
index 0000000..a0a19dd
--- /dev/null
@@ -0,0 +1,106 @@
+From 404615d7f1dcd4cca200e9a7a9df3a1dcae1dd62 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Tue, 13 Jun 2023 12:25:52 +0200
+Subject: ext2: Drop fragment support
+
+From: Jan Kara <jack@suse.cz>
+
+commit 404615d7f1dcd4cca200e9a7a9df3a1dcae1dd62 upstream.
+
+Ext2 has fields in superblock reserved for subblock allocation support.
+However that never landed. Drop the many years dead code.
+
+Reported-by: syzbot+af5e10f73dbff48f70af@syzkaller.appspotmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext2/ext2.h  |   12 ------------
+ fs/ext2/super.c |   23 ++++-------------------
+ 2 files changed, 4 insertions(+), 31 deletions(-)
+
+--- a/fs/ext2/ext2.h
++++ b/fs/ext2/ext2.h
+@@ -70,10 +70,7 @@ struct mb_cache;
+  * second extended-fs super-block data in memory
+  */
+ struct ext2_sb_info {
+-      unsigned long s_frag_size;      /* Size of a fragment in bytes */
+-      unsigned long s_frags_per_block;/* Number of fragments per block */
+       unsigned long s_inodes_per_block;/* Number of inodes per block */
+-      unsigned long s_frags_per_group;/* Number of fragments in a group */
+       unsigned long s_blocks_per_group;/* Number of blocks in a group */
+       unsigned long s_inodes_per_group;/* Number of inodes in a group */
+       unsigned long s_itb_per_group;  /* Number of inode table blocks per group */
+@@ -189,15 +186,6 @@ static inline struct ext2_sb_info *EXT2_
+ #define EXT2_FIRST_INO(s)             (EXT2_SB(s)->s_first_ino)
+ /*
+- * Macro-instructions used to manage fragments
+- */
+-#define EXT2_MIN_FRAG_SIZE            1024
+-#define       EXT2_MAX_FRAG_SIZE              4096
+-#define EXT2_MIN_FRAG_LOG_SIZE                  10
+-#define EXT2_FRAG_SIZE(s)             (EXT2_SB(s)->s_frag_size)
+-#define EXT2_FRAGS_PER_BLOCK(s)               (EXT2_SB(s)->s_frags_per_block)
+-
+-/*
+  * Structure of a blocks group descriptor
+  */
+ struct ext2_group_desc
+--- a/fs/ext2/super.c
++++ b/fs/ext2/super.c
+@@ -668,10 +668,9 @@ static int ext2_setup_super (struct supe
+               es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT);
+       le16_add_cpu(&es->s_mnt_count, 1);
+       if (test_opt (sb, DEBUG))
+-              ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, fs=%lu, gc=%lu, "
++              ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, gc=%lu, "
+                       "bpg=%lu, ipg=%lu, mo=%04lx]",
+                       EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize,
+-                      sbi->s_frag_size,
+                       sbi->s_groups_count,
+                       EXT2_BLOCKS_PER_GROUP(sb),
+                       EXT2_INODES_PER_GROUP(sb),
+@@ -1012,14 +1011,7 @@ static int ext2_fill_super(struct super_
+               }
+       }
+-      sbi->s_frag_size = EXT2_MIN_FRAG_SIZE <<
+-                                 le32_to_cpu(es->s_log_frag_size);
+-      if (sbi->s_frag_size == 0)
+-              goto cantfind_ext2;
+-      sbi->s_frags_per_block = sb->s_blocksize / sbi->s_frag_size;
+-
+       sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
+-      sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
+       sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
+       sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb);
+@@ -1045,11 +1037,10 @@ static int ext2_fill_super(struct super_
+               goto failed_mount;
+       }
+-      if (sb->s_blocksize != sbi->s_frag_size) {
++      if (es->s_log_frag_size != es->s_log_block_size) {
+               ext2_msg(sb, KERN_ERR,
+-                      "error: fragsize %lu != blocksize %lu"
+-                      "(not supported yet)",
+-                      sbi->s_frag_size, sb->s_blocksize);
++                      "error: fragsize log %u != blocksize log %u",
++                      le32_to_cpu(es->s_log_frag_size), sb->s_blocksize_bits);
+               goto failed_mount;
+       }
+@@ -1066,12 +1057,6 @@ static int ext2_fill_super(struct super_
+                       sbi->s_blocks_per_group, sbi->s_inodes_per_group + 3);
+               goto failed_mount;
+       }
+-      if (sbi->s_frags_per_group > sb->s_blocksize * 8) {
+-              ext2_msg(sb, KERN_ERR,
+-                      "error: #fragments per group too big: %lu",
+-                      sbi->s_frags_per_group);
+-              goto failed_mount;
+-      }
+       if (sbi->s_inodes_per_group < sbi->s_inodes_per_block ||
+           sbi->s_inodes_per_group > sb->s_blocksize * 8) {
+               ext2_msg(sb, KERN_ERR,
diff --git a/queue-6.1/f2fs-fix-to-do-sanity-check-on-direct-node-in-truncate_dnode.patch b/queue-6.1/f2fs-fix-to-do-sanity-check-on-direct-node-in-truncate_dnode.patch
new file mode 100644 (file)
index 0000000..d2a0740
--- /dev/null
@@ -0,0 +1,144 @@
+From a6ec83786ab9f13f25fb18166dee908845713a95 Mon Sep 17 00:00:00 2001
+From: Chao Yu <chao@kernel.org>
+Date: Thu, 29 Jun 2023 19:11:44 +0800
+Subject: f2fs: fix to do sanity check on direct node in truncate_dnode()
+
+From: Chao Yu <chao@kernel.org>
+
+commit a6ec83786ab9f13f25fb18166dee908845713a95 upstream.
+
+syzbot reports below bug:
+
+BUG: KASAN: slab-use-after-free in f2fs_truncate_data_blocks_range+0x122a/0x14c0 fs/f2fs/file.c:574
+Read of size 4 at addr ffff88802a25c000 by task syz-executor148/5000
+
+CPU: 1 PID: 5000 Comm: syz-executor148 Not tainted 6.4.0-rc7-syzkaller-00041-ge660abd551f1 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0xd9/0x150 lib/dump_stack.c:106
+ print_address_description.constprop.0+0x2c/0x3c0 mm/kasan/report.c:351
+ print_report mm/kasan/report.c:462 [inline]
+ kasan_report+0x11c/0x130 mm/kasan/report.c:572
+ f2fs_truncate_data_blocks_range+0x122a/0x14c0 fs/f2fs/file.c:574
+ truncate_dnode+0x229/0x2e0 fs/f2fs/node.c:944
+ f2fs_truncate_inode_blocks+0x64b/0xde0 fs/f2fs/node.c:1154
+ f2fs_do_truncate_blocks+0x4ac/0xf30 fs/f2fs/file.c:721
+ f2fs_truncate_blocks+0x7b/0x300 fs/f2fs/file.c:749
+ f2fs_truncate.part.0+0x4a5/0x630 fs/f2fs/file.c:799
+ f2fs_truncate include/linux/fs.h:825 [inline]
+ f2fs_setattr+0x1738/0x2090 fs/f2fs/file.c:1006
+ notify_change+0xb2c/0x1180 fs/attr.c:483
+ do_truncate+0x143/0x200 fs/open.c:66
+ handle_truncate fs/namei.c:3295 [inline]
+ do_open fs/namei.c:3640 [inline]
+ path_openat+0x2083/0x2750 fs/namei.c:3791
+ do_filp_open+0x1ba/0x410 fs/namei.c:3818
+ do_sys_openat2+0x16d/0x4c0 fs/open.c:1356
+ do_sys_open fs/open.c:1372 [inline]
+ __do_sys_creat fs/open.c:1448 [inline]
+ __se_sys_creat fs/open.c:1442 [inline]
+ __x64_sys_creat+0xcd/0x120 fs/open.c:1442
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+The root cause is, inodeA references inodeB via inodeB's ino, once inodeA
+is truncated, it calls truncate_dnode() to truncate data blocks in inodeB's
+node page, it traverse mapping data from node->i.i_addr[0] to
+node->i.i_addr[ADDRS_PER_BLOCK() - 1], result in out-of-boundary access.
+
+This patch fixes to add sanity check on dnode page in truncate_dnode(),
+so that, it can help to avoid triggering such issue, and once it encounters
+such issue, it will record newly introduced ERROR_INVALID_NODE_REFERENCE
+error into superblock, later fsck can detect such issue and try repairing.
+
+Also, it removes f2fs_truncate_data_blocks() for cleanup due to the
+function has only one caller, and uses f2fs_truncate_data_blocks_range()
+instead.
+
+Reported-and-tested-by: syzbot+12cb4425b22169b52036@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-f2fs-devel/000000000000f3038a05fef867f8@google.com
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/f2fs.h          |    1 -
+ fs/f2fs/file.c          |    5 -----
+ fs/f2fs/node.c          |   14 ++++++++++++--
+ include/linux/f2fs_fs.h |    1 +
+ 4 files changed, 13 insertions(+), 8 deletions(-)
+
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3431,7 +3431,6 @@ static inline bool __is_valid_data_blkad
+  * file.c
+  */
+ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
+-void f2fs_truncate_data_blocks(struct dnode_of_data *dn);
+ int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock);
+ int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock);
+ int f2fs_truncate(struct inode *inode);
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -628,11 +628,6 @@ void f2fs_truncate_data_blocks_range(str
+                                        dn->ofs_in_node, nr_free);
+ }
+-void f2fs_truncate_data_blocks(struct dnode_of_data *dn)
+-{
+-      f2fs_truncate_data_blocks_range(dn, ADDRS_PER_BLOCK(dn->inode));
+-}
+-
+ static int truncate_partial_data_page(struct inode *inode, u64 from,
+                                                               bool cache_only)
+ {
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -923,6 +923,7 @@ static int truncate_node(struct dnode_of
+ static int truncate_dnode(struct dnode_of_data *dn)
+ {
++      struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
+       struct page *page;
+       int err;
+@@ -930,16 +931,25 @@ static int truncate_dnode(struct dnode_o
+               return 1;
+       /* get direct node */
+-      page = f2fs_get_node_page(F2FS_I_SB(dn->inode), dn->nid);
++      page = f2fs_get_node_page(sbi, dn->nid);
+       if (PTR_ERR(page) == -ENOENT)
+               return 1;
+       else if (IS_ERR(page))
+               return PTR_ERR(page);
++      if (IS_INODE(page) || ino_of_node(page) != dn->inode->i_ino) {
++              f2fs_err(sbi, "incorrect node reference, ino: %lu, nid: %u, ino_of_node: %u",
++                              dn->inode->i_ino, dn->nid, ino_of_node(page));
++              set_sbi_flag(sbi, SBI_NEED_FSCK);
++              f2fs_handle_error(sbi, ERROR_INVALID_NODE_REFERENCE);
++              f2fs_put_page(page, 1);
++              return -EFSCORRUPTED;
++      }
++
+       /* Make dnode_of_data for parameter */
+       dn->node_page = page;
+       dn->ofs_in_node = 0;
+-      f2fs_truncate_data_blocks(dn);
++      f2fs_truncate_data_blocks_range(dn, ADDRS_PER_BLOCK(dn->inode));
+       err = truncate_node(dn);
+       if (err) {
+               f2fs_put_page(page, 1);
+--- a/include/linux/f2fs_fs.h
++++ b/include/linux/f2fs_fs.h
+@@ -104,6 +104,7 @@ enum f2fs_error {
+       ERROR_INCONSISTENT_SIT,
+       ERROR_CORRUPTED_VERITY_XATTR,
+       ERROR_CORRUPTED_XATTR,
++      ERROR_INVALID_NODE_REFERENCE,
+       ERROR_MAX,
+ };
diff --git a/queue-6.1/fs-protect-reconfiguration-of-sb-read-write-from-racing-writes.patch b/queue-6.1/fs-protect-reconfiguration-of-sb-read-write-from-racing-writes.patch
new file mode 100644 (file)
index 0000000..c780307
--- /dev/null
@@ -0,0 +1,68 @@
+From c541dce86c537714b6761a79a969c1623dfa222b Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 15 Jun 2023 13:38:48 +0200
+Subject: fs: Protect reconfiguration of sb read-write from racing writes
+
+From: Jan Kara <jack@suse.cz>
+
+commit c541dce86c537714b6761a79a969c1623dfa222b upstream.
+
+The reconfigure / remount code takes a lot of effort to protect
+filesystem's reconfiguration code from racing writes on remounting
+read-only. However during remounting read-only filesystem to read-write
+mode userspace writes can start immediately once we clear SB_RDONLY
+flag. This is inconvenient for example for ext4 because we need to do
+some writes to the filesystem (such as preparation of quota files)
+before we can take userspace writes so we are clearing SB_RDONLY flag
+before we are fully ready to accept userpace writes and syzbot has found
+a way to exploit this [1]. Also as far as I'm reading the code
+the filesystem remount code was protected from racing writes in the
+legacy mount path by the mount's MNT_READONLY flag so this is relatively
+new problem. It is actually fairly easy to protect remount read-write
+from racing writes using sb->s_readonly_remount flag so let's just do
+that instead of having to workaround these races in the filesystem code.
+
+[1] https://lore.kernel.org/all/00000000000006a0df05f6667499@google.com/T/
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20230615113848.8439-1-jack@suse.cz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/super.c |   11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/fs/super.c
++++ b/fs/super.c
+@@ -904,6 +904,7 @@ int reconfigure_super(struct fs_context
+       struct super_block *sb = fc->root->d_sb;
+       int retval;
+       bool remount_ro = false;
++      bool remount_rw = false;
+       bool force = fc->sb_flags & SB_FORCE;
+       if (fc->sb_flags_mask & ~MS_RMT_MASK)
+@@ -921,7 +922,7 @@ int reconfigure_super(struct fs_context
+                   bdev_read_only(sb->s_bdev))
+                       return -EACCES;
+ #endif
+-
++              remount_rw = !(fc->sb_flags & SB_RDONLY) && sb_rdonly(sb);
+               remount_ro = (fc->sb_flags & SB_RDONLY) && !sb_rdonly(sb);
+       }
+@@ -951,6 +952,14 @@ int reconfigure_super(struct fs_context
+                       if (retval)
+                               return retval;
+               }
++      } else if (remount_rw) {
++              /*
++               * We set s_readonly_remount here to protect filesystem's
++               * reconfigure code from writes from userspace until
++               * reconfigure finishes.
++               */
++              sb->s_readonly_remount = 1;
++              smp_wmb();
+       }
+       if (fc->ops->reconfigure) {
diff --git a/queue-6.1/io_uring-annotate-offset-timeout-races.patch b/queue-6.1/io_uring-annotate-offset-timeout-races.patch
new file mode 100644 (file)
index 0000000..0f1e9ef
--- /dev/null
@@ -0,0 +1,34 @@
+From 5498bf28d8f2bd63a46ad40f4427518615fb793f Mon Sep 17 00:00:00 2001
+From: Pavel Begunkov <asml.silence@gmail.com>
+Date: Fri, 19 May 2023 15:21:16 +0100
+Subject: io_uring: annotate offset timeout races
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+commit 5498bf28d8f2bd63a46ad40f4427518615fb793f upstream.
+
+It's racy to read ->cached_cq_tail without taking proper measures
+(usually grabbing ->completion_lock) as timeout requests with CQE
+offsets do, however they have never had a good semantics for from
+when they start counting. Annotate racy reads with data_race().
+
+Reported-by: syzbot+cb265db2f3f3468ef436@syzkaller.appspotmail.com
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Link: https://lore.kernel.org/r/4de3685e185832a92a572df2be2c735d2e21a83d.1684506056.git.asml.silence@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/timeout.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/io_uring/timeout.c
++++ b/io_uring/timeout.c
+@@ -545,7 +545,7 @@ int io_timeout(struct io_kiocb *req, uns
+               goto add;
+       }
+-      tail = ctx->cached_cq_tail - atomic_read(&ctx->cq_timeouts);
++      tail = data_race(ctx->cached_cq_tail) - atomic_read(&ctx->cq_timeouts);
+       timeout->target_seq = tail + off;
+       /* Update the last seq here in case io_flush_timeouts() hasn't.
diff --git a/queue-6.1/net-usbnet-fix-warning-in-usbnet_start_xmit-usb_submit_urb.patch b/queue-6.1/net-usbnet-fix-warning-in-usbnet_start_xmit-usb_submit_urb.patch
new file mode 100644 (file)
index 0000000..b055f61
--- /dev/null
@@ -0,0 +1,77 @@
+From 5e1627cb43ddf1b24b92eb26f8d958a3f5676ccb Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 12 Jul 2023 10:15:10 -0400
+Subject: net: usbnet: Fix WARNING in usbnet_start_xmit/usb_submit_urb
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 5e1627cb43ddf1b24b92eb26f8d958a3f5676ccb upstream.
+
+The syzbot fuzzer identified a problem in the usbnet driver:
+
+usb 1-1: BOGUS urb xfer, pipe 3 != type 1
+WARNING: CPU: 0 PID: 754 at drivers/usb/core/urb.c:504 usb_submit_urb+0xed6/0x1880 drivers/usb/core/urb.c:504
+Modules linked in:
+CPU: 0 PID: 754 Comm: kworker/0:2 Not tainted 6.4.0-rc7-syzkaller-00014-g692b7dc87ca6 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023
+Workqueue: mld mld_ifc_work
+RIP: 0010:usb_submit_urb+0xed6/0x1880 drivers/usb/core/urb.c:504
+Code: 7c 24 18 e8 2c b4 5b fb 48 8b 7c 24 18 e8 42 07 f0 fe 41 89 d8 44 89 e1 4c 89 ea 48 89 c6 48 c7 c7 a0 c9 fc 8a e8 5a 6f 23 fb <0f> 0b e9 58 f8 ff ff e8 fe b3 5b fb 48 81 c5 c0 05 00 00 e9 84 f7
+RSP: 0018:ffffc9000463f568 EFLAGS: 00010086
+RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000
+RDX: ffff88801eb28000 RSI: ffffffff814c03b7 RDI: 0000000000000001
+RBP: ffff8881443b7190 R08: 0000000000000001 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000003
+R13: ffff88802a77cb18 R14: 0000000000000003 R15: ffff888018262500
+FS:  0000000000000000(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000556a99c15a18 CR3: 0000000028c71000 CR4: 0000000000350ef0
+Call Trace:
+ <TASK>
+ usbnet_start_xmit+0xfe5/0x2190 drivers/net/usb/usbnet.c:1453
+ __netdev_start_xmit include/linux/netdevice.h:4918 [inline]
+ netdev_start_xmit include/linux/netdevice.h:4932 [inline]
+ xmit_one net/core/dev.c:3578 [inline]
+ dev_hard_start_xmit+0x187/0x700 net/core/dev.c:3594
+...
+
+This bug is caused by the fact that usbnet trusts the bulk endpoint
+addresses its probe routine receives in the driver_info structure, and
+it does not check to see that these endpoints actually exist and have
+the expected type and directions.
+
+The fix is simply to add such a check.
+
+Reported-and-tested-by: syzbot+63ee658b9a100ffadbe2@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-usb/000000000000a56e9105d0cec021@google.com/
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: Oliver Neukum <oneukum@suse.com>
+Link: https://lore.kernel.org/r/ea152b6d-44df-4f8a-95c6-4db51143dcc1@rowland.harvard.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/usbnet.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -1770,6 +1770,10 @@ usbnet_probe (struct usb_interface *udev
+       } else if (!info->in || !info->out)
+               status = usbnet_get_endpoints (dev, udev);
+       else {
++              u8 ep_addrs[3] = {
++                      info->in + USB_DIR_IN, info->out + USB_DIR_OUT, 0
++              };
++
+               dev->in = usb_rcvbulkpipe (xdev, info->in);
+               dev->out = usb_sndbulkpipe (xdev, info->out);
+               if (!(info->flags & FLAG_NO_SETINT))
+@@ -1779,6 +1783,8 @@ usbnet_probe (struct usb_interface *udev
+               else
+                       status = 0;
++              if (status == 0 && !usb_check_bulk_endpoints(udev, ep_addrs))
++                      status = -EINVAL;
+       }
+       if (status >= 0 && dev->status)
+               status = init_status (dev, udev);
index 7fe2d1ef20921e54df154343eeb695f5e740ddbb..9b7460a374d1316bdc86420de5e74b1073328841 100644 (file)
@@ -102,3 +102,9 @@ fs-ntfs3-use-__gfp_nowarn-allocation-at-ntfs_load_attr_list.patch
 fs-sysv-null-check-to-prevent-null-ptr-deref-bug.patch
 bluetooth-l2cap-fix-use-after-free-in-l2cap_sock_ready_cb.patch
 debugobjects-recheck-debug_objects_enabled-before-reporting.patch
+net-usbnet-fix-warning-in-usbnet_start_xmit-usb_submit_urb.patch
+fs-protect-reconfiguration-of-sb-read-write-from-racing-writes.patch
+ext2-drop-fragment-support.patch
+btrfs-remove-bug_on-s-in-add_new_free_space.patch
+f2fs-fix-to-do-sanity-check-on-direct-node-in-truncate_dnode.patch
+io_uring-annotate-offset-timeout-races.patch