summaryrefslogtreecommitdiff
path: root/fs/ext2
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2023-03-01 11:59:39 +0100
committerJan Kara <jack@suse.cz>2023-03-06 16:42:10 +0100
commit62aeb94433fcec80241754b70d0d1836d5926b0a (patch)
tree5b191d6bd8f8289d41507f3f67728d6ebf29134e /fs/ext2
parente9cd1d9a34131fb56bef469d4e1cd31bd1b515e2 (diff)
downloadlinux-next-62aeb94433fcec80241754b70d0d1836d5926b0a.tar.gz
ext2: Check block size validity during mount
Check that log of block size stored in the superblock has sensible value. Otherwise the shift computing the block size can overflow leading to undefined behavior. Reported-by: syzbot+4fec412f59eba8c01b77@syzkaller.appspotmail.com Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext2')
-rw-r--r--fs/ext2/ext2.h1
-rw-r--r--fs/ext2/super.c7
2 files changed, 8 insertions, 0 deletions
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 6c8e838bb278..8244366862e4 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -180,6 +180,7 @@ static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb)
#define EXT2_MIN_BLOCK_SIZE 1024
#define EXT2_MAX_BLOCK_SIZE 65536
#define EXT2_MIN_BLOCK_LOG_SIZE 10
+#define EXT2_MAX_BLOCK_LOG_SIZE 16
#define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize)
#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits)
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 69c88facfe90..f342f347a695 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -945,6 +945,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
goto failed_mount;
}
+ if (le32_to_cpu(es->s_log_block_size) >
+ (EXT2_MAX_BLOCK_LOG_SIZE - BLOCK_SIZE_BITS)) {
+ ext2_msg(sb, KERN_ERR,
+ "Invalid log block size: %u",
+ le32_to_cpu(es->s_log_block_size));
+ goto failed_mount;
+ }
blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
if (test_opt(sb, DAX)) {