From: Simon Glass <simon.gl...@canonical.com> Some memory allocations make use of data from the disk, so add some overflow checks.
Adjust LOG2_BLOCK_SIZE() so it is easier to read. Signed-off-by: Simon Glass <simon.gl...@canonical.com> --- Changes in v2: - Use Linux macros instead of gcc built-ins fs/ext4/ext4_write.c | 25 +++++++++++++++++++++---- include/ext_common.h | 3 +-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c index d109ed6e90d..a9a53214dce 100644 --- a/fs/ext4/ext4_write.c +++ b/fs/ext4/ext4_write.c @@ -25,6 +25,7 @@ #include <malloc.h> #include <memalign.h> #include <part.h> +#include <linux/overflow.h> #include <linux/stat.h> #include <div64.h> #include "ext4_common.h" @@ -108,8 +109,15 @@ int ext4fs_get_bgdtable(void) { int status; struct ext_filesystem *fs = get_fs(); - int gdsize_total = ROUND(fs->no_blkgrp * fs->gdsize, fs->blksz); + size_t alloc_size; + int gdsize_total; + + if (check_mul_overflow(fs->no_blkgrp, fs->gdsize, &alloc_size)) + return -1; + gdsize_total = ROUND(alloc_size, fs->blksz); fs->no_blk_pergdt = gdsize_total / fs->blksz; + if (!fs->no_blk_pergdt) + return -1; /* allocate memory for gdtable */ fs->gdtable = zalloc(gdsize_total); @@ -117,7 +125,7 @@ int ext4fs_get_bgdtable(void) return -ENOMEM; /* read the group descriptor table */ status = ext4fs_devread((lbaint_t)fs->gdtable_blkno * fs->sect_perblk, - 0, fs->blksz * fs->no_blk_pergdt, fs->gdtable); + 0, gdsize_total, fs->gdtable); if (status == 0) goto fail; @@ -599,10 +607,17 @@ int ext4fs_init(void) int i; uint32_t real_free_blocks = 0; struct ext_filesystem *fs = get_fs(); + size_t alloc_size; + + /* check for a reasonable block size, no more than 64K */ + if (LOG2_BLOCK_SIZE(ext4fs_root) > 16) + goto fail; /* populate fs */ fs->blksz = EXT2_BLOCK_SIZE(ext4fs_root); fs->sect_perblk = fs->blksz >> fs->dev_desc->log2blksz; + if (!fs->sect_perblk) + goto fail; /* get the superblock */ fs->sb = zalloc(SUPERBLOCK_SIZE); @@ -629,7 +644,9 @@ int ext4fs_init(void) } /* load all the available bitmap block of the partition */ - fs->blk_bmaps = zalloc(fs->no_blkgrp * sizeof(char *)); + if (check_mul_overflow(fs->no_blkgrp, sizeof(char *), &alloc_size)) + goto fail; + fs->blk_bmaps = zalloc(alloc_size); if (!fs->blk_bmaps) goto fail; for (i = 0; i < fs->no_blkgrp; i++) { @@ -649,7 +666,7 @@ int ext4fs_init(void) } /* load all the available inode bitmap of the partition */ - fs->inode_bmaps = zalloc(fs->no_blkgrp * sizeof(unsigned char *)); + fs->inode_bmaps = zalloc(alloc_size); if (!fs->inode_bmaps) goto fail; for (i = 0; i < fs->no_blkgrp; i++) { diff --git a/include/ext_common.h b/include/ext_common.h index 6e17fbd2771..35d3a1844eb 100644 --- a/include/ext_common.h +++ b/include/ext_common.h @@ -67,8 +67,7 @@ struct cmd_tbl; #define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data)) /* Log2 size of ext2 block in bytes. */ -#define LOG2_BLOCK_SIZE(data) (le32_to_cpu \ - (data->sblock.log2_block_size) \ +#define LOG2_BLOCK_SIZE(data) (le32_to_cpu((data)->sblock.log2_block_size) \ + EXT2_MIN_BLOCK_LOG_SIZE) #define EXT2_FT_DIR 2 -- 2.43.0 base-commit: 5841e78ed6ebd31b26553003e880be378b232cd9 branch: sec2