lkml.org 
[lkml]   [2004]   [Nov]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] don't divide by zero on bad ext2 fs
Experimented a bit more with mounting a bad ext2 filesystem.
An immediate crash was caused by zero EXT2_BLOCKS_PER_GROUP(sb).
The patch below (relative to 2.6.9) adds a few checks to make sure
that things we divide by are not zero.

Andries

diff -uprN -X /linux/dontdiff a/fs/ext2/super.c b/fs/ext2/super.c
--- a/fs/ext2/super.c 2004-10-30 21:44:02.000000000 +0200
+++ b/fs/ext2/super.c 2004-11-05 01:48:32.000000000 +0100
@@ -595,12 +595,9 @@ static int ext2_fill_super(struct super_
sbi->s_es = es;
sb->s_magic = le16_to_cpu(es->s_magic);
sb->s_flags |= MS_ONE_SECOND;
- if (sb->s_magic != EXT2_SUPER_MAGIC) {
- if (!silent)
- printk ("VFS: Can't find ext2 filesystem on dev %s.\n",
- sb->s_id);
- goto failed_mount;
- }
+
+ if (sb->s_magic != EXT2_SUPER_MAGIC)
+ goto cantfind_ext2;

/* Set defaults before we parse the mount options */
def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
@@ -655,7 +652,9 @@ static int ext2_fill_super(struct super_
sb->s_id, le32_to_cpu(features));
goto failed_mount;
}
+
blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
+
/* If the blocksize doesn't match, re-read the thing.. */
if (sb->s_blocksize != blocksize) {
brelse(bh);
@@ -697,35 +696,36 @@ static int ext2_fill_super(struct super_
goto failed_mount;
}
}
+
sbi->s_frag_size = EXT2_MIN_FRAG_SIZE <<
le32_to_cpu(es->s_log_frag_size);
- if (sbi->s_frag_size)
- sbi->s_frags_per_block = sb->s_blocksize /
- sbi->s_frag_size;
- else
- sb->s_magic = 0;
+ if (sbi->s_frag_size == 0)
+ goto cantfind_ext2;
+ sbi->s_frags_per_block = sb->s_blocksize / sbi->s_frag_size;
+
sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
- sbi->s_inodes_per_block = sb->s_blocksize /
- EXT2_INODE_SIZE(sb);
+
+ if (EXT2_INODE_SIZE(sb) == 0)
+ goto cantfind_ext2;
+ sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb);
+ if (sbi->s_inodes_per_block == 0)
+ goto cantfind_ext2;
sbi->s_itb_per_group = sbi->s_inodes_per_group /
- sbi->s_inodes_per_block;
+ sbi->s_inodes_per_block;
sbi->s_desc_per_block = sb->s_blocksize /
- sizeof (struct ext2_group_desc);
+ sizeof (struct ext2_group_desc);
sbi->s_sbh = bh;
sbi->s_mount_state = le16_to_cpu(es->s_state);
sbi->s_addr_per_block_bits =
log2 (EXT2_ADDR_PER_BLOCK(sb));
sbi->s_desc_per_block_bits =
log2 (EXT2_DESC_PER_BLOCK(sb));
- if (sb->s_magic != EXT2_SUPER_MAGIC) {
- if (!silent)
- printk ("VFS: Can't find an ext2 filesystem on dev "
- "%s.\n",
- sb->s_id);
- goto failed_mount;
- }
+
+ if (sb->s_magic != EXT2_SUPER_MAGIC)
+ goto cantfind_ext2;
+
if (sb->s_blocksize != bh->b_size) {
if (!silent)
printk ("VFS: Unsupported blocksize on dev "
@@ -755,6 +755,8 @@ static int ext2_fill_super(struct super_
goto failed_mount;
}

+ if (EXT2_BLOCKS_PER_GROUP(sb) == 0)
+ goto cantfind_ext2;
sbi->s_groups_count = (le32_to_cpu(es->s_blocks_count) -
le32_to_cpu(es->s_first_data_block) +
EXT2_BLOCKS_PER_GROUP(sb) - 1) /
@@ -824,13 +826,19 @@ static int ext2_fill_super(struct super_
percpu_counter_mod(&sbi->s_dirs_counter,
ext2_count_dirs(sb));
return 0;
+
+cantfind_ext2:
+ if (!silent)
+ printk("VFS: Can't find an ext2 filesystem on dev %s.\n",
+ sb->s_id);
+ goto failed_mount;
+
failed_mount2:
for (i = 0; i < db_count; i++)
brelse(sbi->s_group_desc[i]);
failed_mount_group_desc:
kfree(sbi->s_group_desc);
- if (sbi->s_debts)
- kfree(sbi->s_debts);
+ kfree(sbi->s_debts);
failed_mount:
brelse(bh);
failed_sbi:
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 14:07    [W:0.034 / U:0.164 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site