diff options
Diffstat (limited to 'fs/bfs/inode.c')
-rw-r--r-- | fs/bfs/inode.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 0ed57b5ee012..1d2bfafcad7c 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c | |||
@@ -213,6 +213,9 @@ static void bfs_put_super(struct super_block *s) | |||
213 | { | 213 | { |
214 | struct bfs_sb_info *info = BFS_SB(s); | 214 | struct bfs_sb_info *info = BFS_SB(s); |
215 | 215 | ||
216 | if (!info) | ||
217 | return; | ||
218 | |||
216 | brelse(info->si_sbh); | 219 | brelse(info->si_sbh); |
217 | mutex_destroy(&info->bfs_lock); | 220 | mutex_destroy(&info->bfs_lock); |
218 | kfree(info->si_imap); | 221 | kfree(info->si_imap); |
@@ -327,6 +330,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) | |||
327 | unsigned i, imap_len; | 330 | unsigned i, imap_len; |
328 | struct bfs_sb_info *info; | 331 | struct bfs_sb_info *info; |
329 | long ret = -EINVAL; | 332 | long ret = -EINVAL; |
333 | unsigned long i_sblock, i_eblock, i_eoff, s_size; | ||
330 | 334 | ||
331 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 335 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
332 | if (!info) | 336 | if (!info) |
@@ -350,6 +354,12 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) | |||
350 | 354 | ||
351 | s->s_magic = BFS_MAGIC; | 355 | s->s_magic = BFS_MAGIC; |
352 | info->si_sbh = bh; | 356 | info->si_sbh = bh; |
357 | |||
358 | if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end)) { | ||
359 | printf("Superblock is corrupted\n"); | ||
360 | goto out; | ||
361 | } | ||
362 | |||
353 | info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / | 363 | info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / |
354 | sizeof(struct bfs_inode) | 364 | sizeof(struct bfs_inode) |
355 | + BFS_ROOT_INO - 1; | 365 | + BFS_ROOT_INO - 1; |
@@ -397,6 +407,29 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) | |||
397 | 407 | ||
398 | di = (struct bfs_inode *)bh->b_data + off; | 408 | di = (struct bfs_inode *)bh->b_data + off; |
399 | 409 | ||
410 | /* test if filesystem is not corrupted */ | ||
411 | |||
412 | i_eoff = le32_to_cpu(di->i_eoffset); | ||
413 | i_sblock = le32_to_cpu(di->i_sblock); | ||
414 | i_eblock = le32_to_cpu(di->i_eblock); | ||
415 | s_size = le32_to_cpu(bfs_sb->s_end); | ||
416 | |||
417 | if (i_sblock > info->si_blocks || | ||
418 | i_eblock > info->si_blocks || | ||
419 | i_sblock > i_eblock || | ||
420 | i_eoff > s_size || | ||
421 | i_sblock * BFS_BSIZE > i_eoff) { | ||
422 | |||
423 | printf("Inode 0x%08x corrupted\n", i); | ||
424 | |||
425 | brelse(bh); | ||
426 | s->s_root = NULL; | ||
427 | kfree(info->si_imap); | ||
428 | kfree(info); | ||
429 | s->s_fs_info = NULL; | ||
430 | return -EIO; | ||
431 | } | ||
432 | |||
400 | if (!di->i_ino) { | 433 | if (!di->i_ino) { |
401 | info->si_freei++; | 434 | info->si_freei++; |
402 | continue; | 435 | continue; |