[PATCH] gfs2: valid the length of rgrp header

Edward Adam Davis <[email protected]>
Newsgroups dev.linux.lists.gfs2,org.kernel.vger.linux-kernel,org.kvack.linux-mm
Message-ID <[email protected]>
When mounting a deliberately corrupted filesystem image, an excessively
large rgrp header length is used in a call to kzalloc_objs() within
compute_bitstructs(), and the memory allocator cannot handle such a large
allocation request. This triggers [1].

Add a check for the rgrp header length to avoid [1].

[1]
WARNING: mm/page_alloc.c:5280 at __alloc_frozen_pages_noprof+0x2427/0x2dc0 mm/page_alloc.c:5280, CPU#1: syz-executor256/5629
Call Trace:
 alloc_pages_mpol+0x1fb/0x540 mm/mempolicy.c:2490
 ___kmalloc_large_node+0xe5/0x120 mm/slub.c:5274
 __kmalloc_large_node_noprof+0x1c/0x70 mm/slub.c:5305
 __do_kmalloc_node mm/slub.c:5322 [inline]
 __kmalloc_noprof+0x5a1/0x820 mm/slub.c:5359
 _kmalloc_noprof include/linux/slab.h:992 [inline]
 _kzalloc_noprof include/linux/slab.h:1309 [inline]
 compute_bitstructs fs/gfs2/rgrp.c:766 [inline]
 read_rindex_entry+0x4a1/0x1250 fs/gfs2/rgrp.c:931
 gfs2_ri_update+0x6f/0x3b0 fs/gfs2/rgrp.c:1001
 gfs2_rindex_update+0x40b/0x480 fs/gfs2/rgrp.c:1051
 init_inodes+0x1f78/0x2790 fs/gfs2/ops_fstype.c:872
 gfs2_fill_super+0x1d3d/0x2cf0 fs/gfs2/ops_fstype.c:1250
 get_tree_bdev_flags+0x38c/0x620 fs/super.c:1640
 gfs2_get_tree+0x4e/0x280 fs/gfs2/ops_fstype.c:1332
 vfs_get_tree+0x92/0x320 fs/super.c:1700
 fc_mount fs/namespace.c:1198 [inline]

Fixes: bb8d8a6f54c1 ("[GFS2] Fix sign problem in quota/statfs and cleanup _host structures")
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=9d20c3ad7d29227de28d
Tested-by: [email protected]
Signed-off-by: Edward Adam Davis <[email protected]>
---
 fs/gfs2/rgrp.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 5988a165a830..53d097ce668e 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -899,6 +899,7 @@ static int read_rindex_entry(struct gfs2_inode *ip)
 	struct gfs2_rindex buf;
 	int error;
 	struct gfs2_rgrpd *rgd;
+	size_t size;
 
 	if (pos >= i_size_read(&ip->i_inode))
 		return 1;
@@ -917,6 +918,13 @@ static int read_rindex_entry(struct gfs2_inode *ip)
 	rgd->rd_sbd = sdp;
 	rgd->rd_addr = be64_to_cpu(buf.ri_addr);
 	rgd->rd_length = be32_to_cpu(buf.ri_length);
+
+	size = rgd->rd_length * sizeof(struct gfs2_bitmap);
+	if (get_order(size) > MAX_PAGE_ORDER) {
+		error = -EINVAL;
+		goto fail;
+	}
+
 	rgd->rd_data0 = be64_to_cpu(buf.ri_data0);
 	rgd->rd_data = be32_to_cpu(buf.ri_data);
 	rgd->rd_bitbytes = be32_to_cpu(buf.ri_bitbytes);
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.