mirror of https://github.com/vitalif/e2fsprogs
Make ext2fs_check_desc() more stringent to force use of backup superbocks
E2fsck could to do more damage to a filesystem by trying to relocate inode tables due to corrupted block group descriptors, and the relocation could seriously damage the filesystem. This patch enhances ext2fs_check_desk() so it detects more self-inconsistent block group descriptors, including the cases where e2sck might be tempted to relocate the inode table, and reports the block group descriptors as invalid; this will cause e2fsck to attempt to use the backup superblocks, which hopefully have not been trashed. Addresses-Sourceforge-Bug: #1840291 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>bitmap-optimize
parent
7d56e33d1f
commit
009c02baf9
|
@ -63,7 +63,9 @@ int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
|
|||
if (fs->super->s_reserved_gdt_blocks && fs->block_map == bmap)
|
||||
fs->group_desc[group].bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
|
||||
for (j=0; j < old_desc_blocks; j++)
|
||||
ext2fs_mark_block_bitmap(bmap, old_desc_blk + j);
|
||||
if (old_desc_blk + j < fs->super->s_blocks_count)
|
||||
ext2fs_mark_block_bitmap(bmap,
|
||||
old_desc_blk + j);
|
||||
}
|
||||
if (new_desc_blk)
|
||||
ext2fs_mark_block_bitmap(bmap, new_desc_blk);
|
||||
|
|
|
@ -31,41 +31,73 @@
|
|||
*/
|
||||
errcode_t ext2fs_check_desc(ext2_filsys fs)
|
||||
{
|
||||
ext2fs_block_bitmap bmap;
|
||||
errcode_t retval;
|
||||
dgrp_t i;
|
||||
blk_t first_block = fs->super->s_first_data_block;
|
||||
blk_t last_block = fs->super->s_blocks_count-1;
|
||||
blk_t blk, b;
|
||||
int j;
|
||||
|
||||
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
|
||||
|
||||
retval = ext2fs_allocate_block_bitmap(fs, "check_desc map", &bmap);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
for (i = 0; i < fs->group_desc_count; i++)
|
||||
ext2fs_reserve_super_and_bgd(fs, i, bmap);
|
||||
|
||||
for (i = 0; i < fs->group_desc_count; i++) {
|
||||
if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
|
||||
EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
|
||||
first_block = ext2fs_group_first_block(fs, i);
|
||||
last_block = ext2fs_group_last_block(fs, i);
|
||||
if (i == (fs->group_desc_count - 1))
|
||||
last_block = fs->super->s_blocks_count-1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to make sure block bitmap for group is
|
||||
* located within the group.
|
||||
* Check to make sure the block bitmap for group is sane
|
||||
*/
|
||||
if (fs->group_desc[i].bg_block_bitmap < first_block ||
|
||||
fs->group_desc[i].bg_block_bitmap > last_block)
|
||||
return EXT2_ET_GDESC_BAD_BLOCK_MAP;
|
||||
blk = fs->group_desc[i].bg_block_bitmap;
|
||||
if (blk < first_block || blk > last_block ||
|
||||
ext2fs_test_block_bitmap(bmap, blk)) {
|
||||
retval = EXT2_ET_GDESC_BAD_BLOCK_MAP;
|
||||
goto errout;
|
||||
}
|
||||
ext2fs_mark_block_bitmap(bmap, blk);
|
||||
|
||||
/*
|
||||
* Check to make sure inode bitmap for group is
|
||||
* located within the group
|
||||
* Check to make sure the inode bitmap for group is sane
|
||||
*/
|
||||
if (fs->group_desc[i].bg_inode_bitmap < first_block ||
|
||||
fs->group_desc[i].bg_inode_bitmap > last_block)
|
||||
return EXT2_ET_GDESC_BAD_INODE_MAP;
|
||||
blk = fs->group_desc[i].bg_inode_bitmap;
|
||||
if (blk < first_block || blk > last_block ||
|
||||
ext2fs_test_block_bitmap(bmap, blk)) {
|
||||
retval = EXT2_ET_GDESC_BAD_INODE_MAP;
|
||||
goto errout;
|
||||
}
|
||||
ext2fs_mark_block_bitmap(bmap, blk);
|
||||
|
||||
/*
|
||||
* Check to make sure inode table for group is located
|
||||
* within the group
|
||||
* Check to make sure the inode table for group is sane
|
||||
*/
|
||||
if (fs->group_desc[i].bg_inode_table < first_block ||
|
||||
((fs->group_desc[i].bg_inode_table +
|
||||
fs->inode_blocks_per_group - 1) > last_block))
|
||||
return EXT2_ET_GDESC_BAD_INODE_TABLE;
|
||||
blk = fs->group_desc[i].bg_inode_table;
|
||||
if (blk < first_block ||
|
||||
((blk + fs->inode_blocks_per_group - 1) > last_block)) {
|
||||
retval = EXT2_ET_GDESC_BAD_INODE_TABLE;
|
||||
goto errout;
|
||||
}
|
||||
for (j = 0, b = blk; j < fs->inode_blocks_per_group;
|
||||
j++, b++) {
|
||||
if (ext2fs_test_block_bitmap(bmap, b)) {
|
||||
retval = EXT2_ET_GDESC_BAD_INODE_TABLE;
|
||||
goto errout;
|
||||
}
|
||||
ext2fs_mark_block_bitmap(bmap, b);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
errout:
|
||||
ext2fs_free_block_bitmap(bmap);
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -111,15 +111,16 @@ Exit status is 0
|
|||
|
||||
debugfs -R ''set_super_value reserved_gdt_blocks 15679'' -w ./test.img
|
||||
Exit status is 0
|
||||
Corruption found in superblock. (reserved_gdt_blocks = 15679).
|
||||
../e2fsck/e2fsck: Group descriptors look bad... trying backup blocks...
|
||||
Pass 1: Checking inodes, blocks, and sizes
|
||||
Pass 2: Checking directory structure
|
||||
Pass 3: Checking directory connectivity
|
||||
Pass 4: Checking reference counts
|
||||
Pass 5: Checking group summary information
|
||||
|
||||
The superblock could not be read or does not describe a correct ext2
|
||||
filesystem. If the device is valid and it really contains an ext2
|
||||
filesystem (and not swap or ufs or something else), then the superblock
|
||||
is corrupt, and you might try running e2fsck with an alternate superblock:
|
||||
e2fsck -b 1025 <device>
|
||||
|
||||
Exit status is 8
|
||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||
test_filesys: 11/4096 files (0.0% non-contiguous), 2107/16384 blocks
|
||||
Exit status is 1
|
||||
-----------------------------------------------
|
||||
|
||||
debugfs -R ''set_super_value reserved_gdt_blocks 32'' -w ./test.img
|
||||
|
|
Loading…
Reference in New Issue