--- linux-2.6.28-orig/fs/ext4/super.c 2008-12-25 00:26:37.000000000 +0100 +++ linux-2.6.28/fs/ext4/super.c 2009-01-05 23:22:28.000000000 +0100 @@ -1873,8 +1873,8 @@ char *cp; int ret = -EINVAL; int blocksize; - int db_count; - int i; + unsigned int db_count; + unsigned int i; int needs_recovery, has_huge_files; __le32 features; __u64 blocks_count; @@ -2145,9 +2145,11 @@ if (EXT4_BLOCKS_PER_GROUP(sb) == 0) goto cantfind_ext4; - /* ensure blocks_count calculation below doesn't sign-extend */ - if (ext4_blocks_count(es) + EXT4_BLOCKS_PER_GROUP(sb) < - le32_to_cpu(es->s_first_data_block) + 1) { + /* + * ensure blocks_count calculation below doesn't sign-extend + * and after do_div() still blocks_count > 0 + */ + if (ext4_blocks_count(es) < le32_to_cpu(es->s_first_data_block) + 1) { printk(KERN_WARNING "EXT4-fs: bad geometry: block count %llu, " "first data block %u, blocks per group %lu\n", ext4_blocks_count(es), @@ -2160,6 +2162,15 @@ EXT4_BLOCKS_PER_GROUP(sb) - 1); do_div(blocks_count, EXT4_BLOCKS_PER_GROUP(sb)); sbi->s_groups_count = blocks_count; + if (sbi->s_groups_count > ((uint64_t)1<<32) - EXT4_DESC_PER_BLOCK(sb)) { + printk(KERN_WARNING "EXT4-fs: groups count too large: %lu " + "(block count %llu, first data block %u, blocks per group %lu)\n", + sbi->s_groups_count, + ext4_blocks_count(es), + le32_to_cpu(es->s_first_data_block), + EXT4_BLOCKS_PER_GROUP(sb)); + goto failed_mount; + } db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / EXT4_DESC_PER_BLOCK(sb); sbi->s_group_desc = kmalloc(db_count * sizeof(struct buffer_head *),