From 79a9ab145467b95b96a885e6ac0b2cdd22cde516 Mon Sep 17 00:00:00 2001 From: Thiemo Nagel Date: Mon, 19 Jan 2009 23:16:10 -0500 Subject: [PATCH] ext2fs_open2: Add more checks for filesystem consistency Add more checks to assure the filesystem is sane to avoid later division by zero errors. Patch adds consistency checks on superblock to fix serveral crashes: * require EXT2_INODES_PER_GROUP != 0 * require EXT2_DESC_PER_BLOCK != 0 * require s_first_data_block < s_blocks_count * require group_desc_count * EXT2_INODES_PER_GROUP == s_inodes_count Signed-off-by: Thiemo Nagel Signed-off-by: "Theodore Ts'o" --- lib/ext2fs/openfs.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c index 841aa34..cdfeaec 100644 --- a/lib/ext2fs/openfs.c +++ b/lib/ext2fs/openfs.c @@ -243,7 +243,11 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, goto cleanup; } fs->fragsize = EXT2_FRAG_SIZE(fs->super); - fs->inode_blocks_per_group = ((fs->super->s_inodes_per_group * + if (EXT2_INODES_PER_GROUP(fs->super) == 0) { + retval = EXT2_ET_CORRUPT_SUPERBLOCK; + goto cleanup; + } + fs->inode_blocks_per_group = ((EXT2_INODES_PER_GROUP(fs->super) * EXT2_INODE_SIZE(fs->super) + EXT2_BLOCK_SIZE(fs->super) - 1) / EXT2_BLOCK_SIZE(fs->super)); @@ -275,13 +279,20 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, blocks_per_group = EXT2_BLOCKS_PER_GROUP(fs->super); if (blocks_per_group == 0 || blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super) || - fs->inode_blocks_per_group > EXT2_MAX_INODES_PER_GROUP(fs->super)) { + fs->inode_blocks_per_group > EXT2_MAX_INODES_PER_GROUP(fs->super) || + EXT2_DESC_PER_BLOCK(fs->super) == 0 || + fs->super->s_first_data_block >= fs->super->s_blocks_count) { retval = EXT2_ET_CORRUPT_SUPERBLOCK; goto cleanup; } fs->group_desc_count = ext2fs_div_ceil(fs->super->s_blocks_count - fs->super->s_first_data_block, blocks_per_group); + if (fs->group_desc_count * EXT2_INODES_PER_GROUP(fs->super) != + fs->super->s_inodes_count) { + retval = EXT2_ET_CORRUPT_SUPERBLOCK; + goto cleanup; + } fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count, EXT2_DESC_PER_BLOCK(fs->super)); retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize, -- 1.8.3.1