From: Greg Kroah-Hartman Date: Mon, 7 Aug 2023 09:08:52 +0000 (+0200) Subject: 6.4-stable patches X-Git-Tag: v4.14.321~19 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c58d54bcb3d21f1bf98adc52d16f029f821c5593;p=thirdparty%2Fkernel%2Fstable-queue.git 6.4-stable patches 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 mm-gup-do-not-return-0-from-pin_user_pages_fast-for-bad-args.patch net-usbnet-fix-warning-in-usbnet_start_xmit-usb_submit_urb.patch --- diff --git a/queue-6.4/btrfs-remove-bug_on-s-in-add_new_free_space.patch b/queue-6.4/btrfs-remove-bug_on-s-in-add_new_free_space.patch new file mode 100644 index 00000000000..90013c24c48 --- /dev/null +++ b/queue-6.4/btrfs-remove-bug_on-s-in-add_new_free_space.patch @@ -0,0 +1,214 @@ +From d8ccbd21918fd7fa6ce3226cffc22c444228e8ad Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Fri, 30 Jun 2023 16:03:44 +0100 +Subject: btrfs: remove BUG_ON()'s in add_new_free_space() + +From: Filipe Manana + +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 +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -499,12 +499,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, +@@ -517,10 +521,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; +@@ -529,13 +535,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; + } + + /* +@@ -779,8 +787,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; +@@ -795,11 +808,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; +@@ -2290,9 +2302,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); +@@ -2728,9 +2742,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 +@@ -277,8 +277,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 +@@ -1515,9 +1515,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); +@@ -1529,8 +1533,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++; + } + +@@ -1569,6 +1574,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; +@@ -1583,8 +1590,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.4/ext2-drop-fragment-support.patch b/queue-6.4/ext2-drop-fragment-support.patch new file mode 100644 index 00000000000..a0a19dd0307 --- /dev/null +++ b/queue-6.4/ext2-drop-fragment-support.patch @@ -0,0 +1,106 @@ +From 404615d7f1dcd4cca200e9a7a9df3a1dcae1dd62 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Tue, 13 Jun 2023 12:25:52 +0200 +Subject: ext2: Drop fragment support + +From: Jan Kara + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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.4/f2fs-fix-to-do-sanity-check-on-direct-node-in-truncate_dnode.patch b/queue-6.4/f2fs-fix-to-do-sanity-check-on-direct-node-in-truncate_dnode.patch new file mode 100644 index 00000000000..2540cbae989 --- /dev/null +++ b/queue-6.4/f2fs-fix-to-do-sanity-check-on-direct-node-in-truncate_dnode.patch @@ -0,0 +1,144 @@ +From a6ec83786ab9f13f25fb18166dee908845713a95 Mon Sep 17 00:00:00 2001 +From: Chao Yu +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 + +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: + + __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 +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -3445,7 +3445,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 +@@ -627,11 +627,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 +@@ -925,6 +925,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; + +@@ -932,16 +933,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 +@@ -103,6 +103,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.4/fs-protect-reconfiguration-of-sb-read-write-from-racing-writes.patch b/queue-6.4/fs-protect-reconfiguration-of-sb-read-write-from-racing-writes.patch new file mode 100644 index 00000000000..eba69a8e628 --- /dev/null +++ b/queue-6.4/fs-protect-reconfiguration-of-sb-read-write-from-racing-writes.patch @@ -0,0 +1,68 @@ +From c541dce86c537714b6761a79a969c1623dfa222b Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 15 Jun 2023 13:38:48 +0200 +Subject: fs: Protect reconfiguration of sb read-write from racing writes + +From: Jan Kara + +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 +Message-Id: <20230615113848.8439-1-jack@suse.cz> +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/super.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/fs/super.c ++++ b/fs/super.c +@@ -903,6 +903,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) +@@ -920,7 +921,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); + } + +@@ -950,6 +951,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.4/io_uring-annotate-offset-timeout-races.patch b/queue-6.4/io_uring-annotate-offset-timeout-races.patch new file mode 100644 index 00000000000..b77a77421c0 --- /dev/null +++ b/queue-6.4/io_uring-annotate-offset-timeout-races.patch @@ -0,0 +1,34 @@ +From 5498bf28d8f2bd63a46ad40f4427518615fb793f Mon Sep 17 00:00:00 2001 +From: Pavel Begunkov +Date: Fri, 19 May 2023 15:21:16 +0100 +Subject: io_uring: annotate offset timeout races + +From: Pavel Begunkov + +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 +Link: https://lore.kernel.org/r/4de3685e185832a92a572df2be2c735d2e21a83d.1684506056.git.asml.silence@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + io_uring/timeout.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/io_uring/timeout.c ++++ b/io_uring/timeout.c +@@ -594,7 +594,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.4/mm-gup-do-not-return-0-from-pin_user_pages_fast-for-bad-args.patch b/queue-6.4/mm-gup-do-not-return-0-from-pin_user_pages_fast-for-bad-args.patch new file mode 100644 index 00000000000..86d1628c11f --- /dev/null +++ b/queue-6.4/mm-gup-do-not-return-0-from-pin_user_pages_fast-for-bad-args.patch @@ -0,0 +1,43 @@ +From 9883c7f84053cec2826ca3c56254601b5ce9cdbe Mon Sep 17 00:00:00 2001 +From: Jason Gunthorpe +Date: Mon, 19 Jun 2023 15:27:25 -0300 +Subject: mm/gup: do not return 0 from pin_user_pages_fast() for bad args + +From: Jason Gunthorpe + +commit 9883c7f84053cec2826ca3c56254601b5ce9cdbe upstream. + +These routines are not intended to return zero, the callers cannot do +anything sane with a 0 return. They should return an error which means +future calls to GUP will not succeed, or they should return some non-zero +number of pinned pages which means GUP should be called again. + +If start + nr_pages overflows it should return -EOVERFLOW to signal the +arguments are invalid. + +Syzkaller keeps tripping on this when fuzzing GUP arguments. + +Link: https://lkml.kernel.org/r/0-v1-3d5ed1f20d50+104-gup_overflow_jgg@nvidia.com +Signed-off-by: Jason Gunthorpe +Reported-by: syzbot+353c7be4964c6253f24a@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/000000000000094fdd05faa4d3a4@google.com +Reviewed-by: John Hubbard +Reviewed-by: Lorenzo Stoakes +Reviewed-by: David Hildenbrand +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/gup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/gup.c ++++ b/mm/gup.c +@@ -2977,7 +2977,7 @@ static int internal_get_user_pages_fast( + start = untagged_addr(start) & PAGE_MASK; + len = nr_pages << PAGE_SHIFT; + if (check_add_overflow(start, len, &end)) +- return 0; ++ return -EOVERFLOW; + if (end > TASK_SIZE_MAX) + return -EFAULT; + if (unlikely(!access_ok((void __user *)start, len))) diff --git a/queue-6.4/net-usbnet-fix-warning-in-usbnet_start_xmit-usb_submit_urb.patch b/queue-6.4/net-usbnet-fix-warning-in-usbnet_start_xmit-usb_submit_urb.patch new file mode 100644 index 00000000000..e796397505e --- /dev/null +++ b/queue-6.4/net-usbnet-fix-warning-in-usbnet_start_xmit-usb_submit_urb.patch @@ -0,0 +1,77 @@ +From 5e1627cb43ddf1b24b92eb26f8d958a3f5676ccb Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 12 Jul 2023 10:15:10 -0400 +Subject: net: usbnet: Fix WARNING in usbnet_start_xmit/usb_submit_urb + +From: Alan Stern + +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: + + 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 +CC: Oliver Neukum +Link: https://lore.kernel.org/r/ea152b6d-44df-4f8a-95c6-4db51143dcc1@rowland.harvard.edu +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/usbnet.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -1775,6 +1775,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)) +@@ -1784,6 +1788,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); diff --git a/queue-6.4/series b/queue-6.4/series index ff4a15295e3..dc21521321a 100644 --- a/queue-6.4/series +++ b/queue-6.4/series @@ -138,3 +138,10 @@ kasan-kmsan-remove-__gfp_kswapd_reclaim-usage-from-kasan-kmsan.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 +mm-gup-do-not-return-0-from-pin_user_pages_fast-for-bad-args.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