From: Greg Kroah-Hartman Date: Wed, 21 Jun 2023 18:44:48 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.14.320~77 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8b7041b22ee442614c6ef137d5a3564b1168ce85;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: nilfs2-reject-devices-with-insufficient-block-count.patch --- diff --git a/queue-4.14/nilfs2-reject-devices-with-insufficient-block-count.patch b/queue-4.14/nilfs2-reject-devices-with-insufficient-block-count.patch new file mode 100644 index 00000000000..5f708524329 --- /dev/null +++ b/queue-4.14/nilfs2-reject-devices-with-insufficient-block-count.patch @@ -0,0 +1,105 @@ +From 92c5d1b860e9581d64baca76779576c0ab0d943d Mon Sep 17 00:00:00 2001 +From: Ryusuke Konishi +Date: Fri, 26 May 2023 11:13:32 +0900 +Subject: nilfs2: reject devices with insufficient block count + +From: Ryusuke Konishi + +commit 92c5d1b860e9581d64baca76779576c0ab0d943d upstream. + +The current sanity check for nilfs2 geometry information lacks checks for +the number of segments stored in superblocks, so even for device images +that have been destructively truncated or have an unusually high number of +segments, the mount operation may succeed. + +This causes out-of-bounds block I/O on file system block reads or log +writes to the segments, the latter in particular causing +"a_ops->writepages" to repeatedly fail, resulting in sync_inodes_sb() to +hang. + +Fix this issue by checking the number of segments stored in the superblock +and avoiding mounting devices that can cause out-of-bounds accesses. To +eliminate the possibility of overflow when calculating the number of +blocks required for the device from the number of segments, this also adds +a helper function to calculate the upper bound on the number of segments +and inserts a check using it. + +Link: https://lkml.kernel.org/r/20230526021332.3431-1-konishi.ryusuke@gmail.com +Signed-off-by: Ryusuke Konishi +Reported-by: syzbot+7d50f1e54a12ba3aeae2@syzkaller.appspotmail.com + Link: https://syzkaller.appspot.com/bug?extid=7d50f1e54a12ba3aeae2 +Tested-by: Ryusuke Konishi +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + fs/nilfs2/the_nilfs.c | 44 +++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 43 insertions(+), 1 deletion(-) + +--- a/fs/nilfs2/the_nilfs.c ++++ b/fs/nilfs2/the_nilfs.c +@@ -384,6 +384,18 @@ unsigned long nilfs_nrsvsegs(struct the_ + 100)); + } + ++/** ++ * nilfs_max_segment_count - calculate the maximum number of segments ++ * @nilfs: nilfs object ++ */ ++static u64 nilfs_max_segment_count(struct the_nilfs *nilfs) ++{ ++ u64 max_count = U64_MAX; ++ ++ do_div(max_count, nilfs->ns_blocks_per_segment); ++ return min_t(u64, max_count, ULONG_MAX); ++} ++ + void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs) + { + nilfs->ns_nsegments = nsegs; +@@ -393,6 +405,8 @@ void nilfs_set_nsegments(struct the_nilf + static int nilfs_store_disk_layout(struct the_nilfs *nilfs, + struct nilfs_super_block *sbp) + { ++ u64 nsegments, nblocks; ++ + if (le32_to_cpu(sbp->s_rev_level) < NILFS_MIN_SUPP_REV) { + nilfs_msg(nilfs->ns_sb, KERN_ERR, + "unsupported revision (superblock rev.=%d.%d, current rev.=%d.%d). Please check the version of mkfs.nilfs(2).", +@@ -439,7 +453,35 @@ static int nilfs_store_disk_layout(struc + return -EINVAL; + } + +- nilfs_set_nsegments(nilfs, le64_to_cpu(sbp->s_nsegments)); ++ nsegments = le64_to_cpu(sbp->s_nsegments); ++ if (nsegments > nilfs_max_segment_count(nilfs)) { ++ nilfs_msg(nilfs->ns_sb, KERN_ERR, ++ "segment count %llu exceeds upper limit (%llu segments)", ++ (unsigned long long)nsegments, ++ (unsigned long long)nilfs_max_segment_count(nilfs)); ++ return -EINVAL; ++ } ++ ++ nblocks = (u64)i_size_read(nilfs->ns_sb->s_bdev->bd_inode) >> ++ nilfs->ns_sb->s_blocksize_bits; ++ if (nblocks) { ++ u64 min_block_count = nsegments * nilfs->ns_blocks_per_segment; ++ /* ++ * To avoid failing to mount early device images without a ++ * second superblock, exclude that block count from the ++ * "min_block_count" calculation. ++ */ ++ ++ if (nblocks < min_block_count) { ++ nilfs_msg(nilfs->ns_sb, KERN_ERR, ++ "total number of segment blocks %llu exceeds device size (%llu blocks)", ++ (unsigned long long)min_block_count, ++ (unsigned long long)nblocks); ++ return -EINVAL; ++ } ++ } ++ ++ nilfs_set_nsegments(nilfs, nsegments); + nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed); + return 0; + } diff --git a/queue-4.14/series b/queue-4.14/series index b7d8268abfe..be077cc7c6c 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -1 +1,2 @@ serial-lantiq-add-missing-interrupt-ack.patch +nilfs2-reject-devices-with-insufficient-block-count.patch