summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2011-01-05 08:00:27 +0100
committerChristophe Grenier <grenier@cgsecurity.org>2011-01-05 08:00:27 +0100
commit130cc8fbde28499c462ccdde1fd2bf613b590b3d (patch)
tree65dbf5bdd7d832476517259485f1a14de44adf46 /src
parentab7f90998dc36f2ab775d02afc14b1968d7537fa (diff)
Detect ext2/3/4 filesystem using group 3 backup superblock when main superblock is damaged in non-partionned media.
Diffstat (limited to 'src')
-rw-r--r--src/partnone.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/partnone.c b/src/partnone.c
index e3140f1..744b265 100644
--- a/src/partnone.c
+++ b/src/partnone.c
@@ -232,6 +232,28 @@ static list_part_t *read_part_none(disk_t *disk, const int verbose, const int sa
if(res>0 && partition->part_offset!=0)
res=0;
}
+ if(res<=0)
+ {
+ int s_log_block_size;
+ for(s_log_block_size=0; s_log_block_size<=2 && res<=0; s_log_block_size++)
+ {
+ /* sparse superblock feature: The groups chosen are 0, 1 and powers of 3, 5 and 7. */
+ /* Checking group 3 */
+ const uint64_t hd_offset=3*(EXT2_MIN_BLOCK_SIZE<<s_log_block_size)*8*(EXT2_MIN_BLOCK_SIZE<<s_log_block_size)+(s_log_block_size==0?2*DEFAULT_SECTOR_SIZE:0);
+ void *data=disk->pread_fast(disk, buffer_disk, 1024, hd_offset);
+ if(data!=NULL)
+ {
+ const struct ext2_super_block *sb=(const struct ext2_super_block*)data;
+ partition->part_offset = hd_offset;
+ if(le16(sb->s_block_group_nr)>0 &&
+ le16(sb->s_magic)==EXT2_SUPER_MAGIC &&
+ recover_EXT2(disk, sb, partition, 0, 0)==0)
+ res=1;
+ if(res>0 && partition->part_offset!=0)
+ res=0;
+ }
+ }
+ }
free(buffer_disk);
if(res<=0)
partition_reset(partition,&arch_none);