summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorThiemo Nagel <thiemo.nagel@ph.tum.de>2009-01-19 23:16:10 -0500
committerTheodore Ts'o <tytso@mit.edu>2009-01-19 23:16:10 -0500
commit79a9ab145467b95b96a885e6ac0b2cdd22cde516 (patch)
treee965a4ddd285b8ae89e13d7425793156eb235495 /lib
parenta7843581f5c862db79286c7e73f5ca76d59dccea (diff)
downloade2fsprogs-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.c15
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,