* [PATCH 5.10 5.15] nilfs2: reject devices with insufficient block count
@ 2023-06-18 18:35 Ryusuke Konishi
2023-06-19 7:49 ` Greg Kroah-Hartman
0 siblings, 1 reply; 2+ messages in thread
From: Ryusuke Konishi @ 2023-06-18 18:35 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable; +Cc: Andrew Morton
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 <konishi.ryusuke@gmail.com>
Reported-by: syzbot+7d50f1e54a12ba3aeae2@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?extid=7d50f1e54a12ba3aeae2
Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
Please apply this patch to the above stable trees instead of the patch
that could not be applied to them. The hang issue reported by syzbot was
confirmed to reproduce on these stable kernels using its reproducer.
This fixes it.
In this patch, "sb_bdev_nr_blocks()" is replaced with its equivalent since
it doesn't yet exist in these kernels. With this tweak, this patch is
applicable from v5.9 to v5.15. Also, this patch has been tested against
the title stable trees.
fs/nilfs2/the_nilfs.c | 44 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 0fa130362816..fe2e7197268b 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -405,6 +405,18 @@ unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs)
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;
@@ -414,6 +426,8 @@ void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs)
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_err(nilfs->ns_sb,
"unsupported revision (superblock rev.=%d.%d, current rev.=%d.%d). Please check the version of mkfs.nilfs(2).",
@@ -457,7 +471,35 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
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_err(nilfs->ns_sb,
+ "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_err(nilfs->ns_sb,
+ "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;
}
--
2.39.3
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH 5.10 5.15] nilfs2: reject devices with insufficient block count
2023-06-18 18:35 [PATCH 5.10 5.15] nilfs2: reject devices with insufficient block count Ryusuke Konishi
@ 2023-06-19 7:49 ` Greg Kroah-Hartman
0 siblings, 0 replies; 2+ messages in thread
From: Greg Kroah-Hartman @ 2023-06-19 7:49 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: stable, Andrew Morton
On Mon, Jun 19, 2023 at 03:35:19AM +0900, Ryusuke Konishi wrote:
> 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 <konishi.ryusuke@gmail.com>
> Reported-by: syzbot+7d50f1e54a12ba3aeae2@syzkaller.appspotmail.com
> Link: https://syzkaller.appspot.com/bug?extid=7d50f1e54a12ba3aeae2
> Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> ---
> Please apply this patch to the above stable trees instead of the patch
> that could not be applied to them. The hang issue reported by syzbot was
> confirmed to reproduce on these stable kernels using its reproducer.
> This fixes it.
>
> In this patch, "sb_bdev_nr_blocks()" is replaced with its equivalent since
> it doesn't yet exist in these kernels. With this tweak, this patch is
> applicable from v5.9 to v5.15. Also, this patch has been tested against
> the title stable trees.
>
Now queued up, thanks.
greg k-h
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-06-19 7:49 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-18 18:35 [PATCH 5.10 5.15] nilfs2: reject devices with insufficient block count Ryusuke Konishi
2023-06-19 7:49 ` Greg Kroah-Hartman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).