diff options
author | Thiemo Nagel <thiemo.nagel@ph.tum.de> | 2009-01-19 23:16:10 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-01-19 23:16:10 -0500 |
commit | 79a9ab145467b95b96a885e6ac0b2cdd22cde516 (patch) | |
tree | e965a4ddd285b8ae89e13d7425793156eb235495 /lib | |
parent | a7843581f5c862db79286c7e73f5ca76d59dccea (diff) | |
download | e2fsprogs-79a9ab145467b95b96a885e6ac0b2cdd22cde516.tar.gz |
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 <thiemo.nagel@ph.tum.de>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ext2fs/openfs.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c index 841aa34b..cdfeaec1 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, |