diff options
author | robi <robi> | 2010-10-02 15:41:49 +0000 |
---|---|---|
committer | robi <robi> | 2010-10-02 15:41:49 +0000 |
commit | 88e4c10b43783c24201e932b6494250b548ed84b (patch) | |
tree | 0e47a288f716c0e6fdf5ce425ebabd9fd3562fa5 | |
parent | 36208b20d0afdd5d26fcaf57fb4b7a384d93157c (diff) |
BUGs:#017547 #017556 #017557 #017559
-rw-r--r-- | src/inode.c | 21 | ||||
-rw-r--r-- | src/inode.h | 2 | ||||
-rw-r--r-- | src/journal.c | 2 | ||||
-rw-r--r-- | src/magic_block_scan.c | 164 | ||||
-rw-r--r-- | src/util.c | 64 |
5 files changed, 162 insertions, 91 deletions
diff --git a/src/inode.c b/src/inode.c index d1f2571..27fff1c 100644 --- a/src/inode.c +++ b/src/inode.c @@ -950,15 +950,16 @@ return 1; //add the ext3 indirect Blocks to the inode -blk_t inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *last, char *buf ){ - blk_t b_blk,block_count, next; +int inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *last, blk_t *next, unsigned char *buf ){ + blk_t b_blk,block_count; blk_t count=0; int i; __u64 i_size = 0; + int ret = 0; i = 0; block_count = 0; - next = 0; + if (! (inode->i_flags & EXT4_EXTENTS_FL)){ while ((i < EXT2_N_BLOCKS) && inode->i_block[i] ) @@ -966,13 +967,13 @@ blk_t inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *la switch (i){ case EXT2_IND_BLOCK : - get_ind_block_len(buf, &block_count, last, &next, &i_size); + ret = get_ind_block_len(buf, &block_count, last, next, &i_size); break; case EXT2_DIND_BLOCK : - get_dind_block_len(buf, &block_count, last, &next, &i_size); + ret = get_dind_block_len(buf, &block_count, last, next, &i_size); break; case EXT2_TIND_BLOCK : - get_tind_block_len(buf, &block_count, last, &next, &i_size); + ret = get_tind_block_len(buf, &block_count, last, next, &i_size); break; default: // printf("faulty Block %u as indirekter_block %d \n", i,blk); @@ -980,7 +981,7 @@ blk_t inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *la break; } - if (i_size){ + if (ret && i_size){ i_size += (((__u64)inode->i_size_high << 32)| inode->i_size); inode->i_size = i_size & 0xffffffff ; inode->i_size_high = i_size >> 32 ; @@ -988,14 +989,14 @@ blk_t inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *la inode->i_block[ i ] = blk; } else - next = 0; + *next = 0; - return next; + return ret; } else{ // printf("ERROR: ext3 indirect block %u ; but is a ext4_inode\n", blk); //FIXME ext4 } - return 1; + return 0; }
\ No newline at end of file diff --git a/src/inode.h b/src/inode.h index bcc0089..80aa711 100644 --- a/src/inode.h +++ b/src/inode.h @@ -69,7 +69,7 @@ struct ring_buf* get_j_inode_list(struct ext2_super_block*, ext2_ino_t);//fill a //functions for the magic scanner struct ext2_inode_large* new_inode(); //create a new inode int inode_add_block(struct ext2_inode_large* , blk_t , __u32); //add a block to inode -blk_t inode_add_meta_block(struct ext2_inode_large*, blk_t, blk_t*, char* ); //add the ext3 indirect Blocks to the inode +int inode_add_meta_block(struct ext2_inode_large*, blk_t, blk_t*, blk_t*,unsigned char* ); //add the ext3 indirect Blocks to the inode #endif diff --git a/src/journal.c b/src/journal.c index e26d66b..c8e8810 100644 --- a/src/journal.c +++ b/src/journal.c @@ -972,7 +972,7 @@ int next_block_bitmap(ext2fs_block_bitmap d_bmap){ } i = 0; -len = fs_bitmap->real_end >> 3; +len = (fs_bitmap->end +1) >> 3; while ((i < len) && (!(*(df_bitmap->bitmap +i)))) i++; return ( i == len) ? 2 : 1 ; diff --git a/src/magic_block_scan.c b/src/magic_block_scan.c index 85bf75d..51cc34d 100644 --- a/src/magic_block_scan.c +++ b/src/magic_block_scan.c @@ -200,6 +200,38 @@ static int check_file_data_possible(struct found_data_t* this, __u32 scan ,unsig +static int check_meta3_block(unsigned char *block_buf, blk_t blk, __u32 size){ + blk_t block, *pb_block; + int i,j ; + + size = (size + 3) & 0xFFFFFC ; + if (! size ) return 0; + + for (i = size-4 ; i>=0 ; i -= 4){ + pb_block = (blk_t*)(block_buf+i); + block = ext2fs_le32_to_cpu(*pb_block); + if( block && (block < current_fs->super->s_blocks_count) && + (ext2fs_test_block_bitmap( d_bmap, block)) && (!ext2fs_test_block_bitmap(bmap,block))){ + if (i) { //work not by sparse file + for (j = i - 4 ; j >= 0 ;j -= 4){ + if (block == ext2fs_le32_to_cpu(*((blk_t*)(block_buf+j)))) + return 0; + } + } + else { + if (block == blk+1) + return 1; + } + + } + else + return 0; + } +} + + + + static int check_indirect_meta3(unsigned char *block_buf){ blk_t *pb_block; blk_t last; @@ -224,34 +256,46 @@ static int check_indirect_meta3(unsigned char *block_buf){ } +static int check_dindirect_meta3(unsigned char * block_buf){ + __u32 *p_blk; + __u32 block; + unsigned char *buf = NULL; + int ret = 0; + + buf = malloc(current_fs->blocksize); + if (buf) { + p_blk = (__u32*) block_buf; + block = ext2fs_le32_to_cpu(*p_blk); + io_channel_read_blk ( current_fs->io, block, 1, buf ); + if (check_meta3_block(buf, block, get_block_len(buf))){ + ret = check_indirect_meta3(buf); + } + free (buf); + } + +return ret; +} -static int check_meta3_block(unsigned char *block_buf, blk_t blk, __u32 size){ - blk_t block, *pb_block; - int i,j ; - size = (size + 3) & 0xFFFFFC ; - if (! size ) return 0; - for (i = size-4 ; i>=0 ; i -= 4){ - pb_block = (blk_t*)(block_buf+i); - block = ext2fs_le32_to_cpu(*pb_block); - if( block && (block < current_fs->super->s_blocks_count) && - (ext2fs_test_block_bitmap( d_bmap, block)) && (!ext2fs_test_block_bitmap(bmap,block))){ - if (i) { - for (j = i - 4 ; j >= 0 ;j -= 4){ - if (block == ext2fs_le32_to_cpu(*((blk_t*)(block_buf+j)))) - return 0; - } - } - else { - if (block == blk+1) - return 1; - } - - } - else - return 0; - } +static int check_tindirect_meta3(unsigned char * block_buf){ + __u32 *p_blk; + __u32 block; + unsigned char *buf = NULL; + int ret = 0; + + buf = malloc(current_fs->blocksize); + if (buf) { + p_blk = (__u32*) block_buf; + block = ext2fs_le32_to_cpu(*p_blk); + io_channel_read_blk ( current_fs->io, block, 1, buf ); + if (check_meta3_block(buf, block, get_block_len(buf))){ + ret = check_dindirect_meta3(buf); + } + free (buf); + } + +return ret; } @@ -330,29 +374,42 @@ static int check_acl_block(unsigned char *block_buf, blk_t blk, __u32 size){ static int add_ext3_file_meta_data(struct found_data_t* this, unsigned char *buf, blk_t blk){ - blk_t next_meta; + blk_t next_meta = 0; + blk_t meta = 0; blk_t last_data = 0; - next_meta = inode_add_meta_block(this->inode , blk, &last_data, buf ); - this->last = last_data; + int ret = 0; - if (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta)))){ - io_channel_read_blk ( current_fs->io, next_meta, 1, buf ); - if (check_meta3_block(buf, blk, get_block_len(buf))){ - next_meta = inode_add_meta_block(this->inode , next_meta , &last_data, buf ); + if (check_indirect_meta3(buf)){ + ret = inode_add_meta_block(this->inode , blk, &last_data, &next_meta, buf ); + this->last = last_data; + } + + if (ret && (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta))))){ + meta = next_meta; + next_meta = 0; + io_channel_read_blk ( current_fs->io, meta, 1, buf ); + + if (check_meta3_block(buf, meta, get_block_len(buf)) && check_dindirect_meta3(buf)){ + ret = inode_add_meta_block(this->inode , meta, &last_data, &next_meta, buf ); this->last = last_data; - if (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta)))){ - io_channel_read_blk ( current_fs->io, next_meta, 1, buf ); + if (ret && (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta))))){ + meta = next_meta; + next_meta = 0; + io_channel_read_blk ( current_fs->io, meta, 1, buf ); - if (check_meta3_block(buf, blk, get_block_len(buf))){ - next_meta = inode_add_meta_block(this->inode , next_meta , &last_data, buf ); + if (check_meta3_block(buf, meta, get_block_len(buf)) && check_tindirect_meta3(buf)){ + ret = inode_add_meta_block(this->inode , meta, &last_data, &next_meta, buf ); this->last = last_data; } - } + + } + } + } -return (next_meta) ? 0 : 1 ; +return ret ; } @@ -365,7 +422,7 @@ static int skip_block(blk_t *p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_ o_blk = (*p_blk) >> 3; p_bmap = (struct ext2fs_struct_loc_generic_bitmap *) bmap; - while (((! *(ds_bmap->bitmap + o_blk)) || (*(ds_bmap->bitmap + o_blk) == 0xff)) && (o_blk < (ds_bmap->real_end >> 3))){ + while (((! *(ds_bmap->bitmap + o_blk)) || (*(ds_bmap->bitmap + o_blk) == 0xff)) && (o_blk < (ds_bmap->end >> 3))){ o_blk ++; flag = 1; } @@ -468,6 +525,8 @@ static int magic_check_block(unsigned char* buf,magic_t cookie , magic_t cookie_ } p_search++; } + if (! (retval & M_APPLI)) + retval |= M_DATA ; goto out; } @@ -537,20 +596,23 @@ static int get_range(blk_t* p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_b blk_t begin; blk_t end; int count=1; - for (begin = *p_blk; begin < ds_bmap->real_end ; begin++){ + for (begin = *p_blk; begin <= ds_bmap->end ; begin++){ if((!(begin & 0x7)) && skip_block(&begin, ds_bmap)){ #ifdef DEBUG_MAGIC_SCAN printf("jump to %d \n",begin); #endif } + *p_blk = begin; + if (begin > ds_bmap->end) + return 0; if (ext2fs_test_block_bitmap ( d_bmap, begin) && (! ext2fs_test_block_bitmap( bmap, begin))) break; } - *p_blk = begin; - if (begin >= ds_bmap->real_end) + + if (begin > ds_bmap->end) return 0; - for (end = begin,count=1 ; ((count < MAX_RANGE) && (end < ds_bmap->real_end)); ){ + for (end = begin,count=1 ; ((count < MAX_RANGE) && (end < ds_bmap->end-1)); ){ if (ext2fs_test_block_bitmap(d_bmap, end+1) && (! ext2fs_test_block_bitmap( bmap, end+1))){ end++; count++; @@ -575,21 +637,21 @@ static int get_full_range(blk_t* p_blk ,struct ext2fs_struct_loc_generic_bitmap int i; errcode_t x; - for (begin = *p_blk; begin < ds_bmap->real_end ; begin++){ + for (begin = *p_blk; begin <= ds_bmap->end ; begin++){ if((!(begin & 0x7)) && skip_block(&begin, ds_bmap)){ #ifdef DEBUG_MAGIC_SCAN printf("jump to %d \n",begin); #endif } + *p_blk = begin; + if (begin > ds_bmap->end) + return 0; if (ext2fs_test_block_bitmap ( d_bmap, begin) && (! ext2fs_test_block_bitmap( bmap, begin))) break; } - *p_blk = begin; - if (begin >= ds_bmap->real_end) - return 0; i = 0; - for (end = begin,count=1 ; ((count <= MAX_RANGE) && (end < ds_bmap->real_end)); ){ + for (end = begin,count=1 ; ((count <= MAX_RANGE) && (end < ds_bmap->end)); ){ if (ext2fs_test_block_bitmap(d_bmap, end) && (! ext2fs_test_block_bitmap( bmap, end))){ count++; if (!begin) @@ -679,7 +741,9 @@ while (ds_retval){ if (d_bmap && ds_retval ){ ds_bmap = (struct ext2fs_struct_loc_generic_bitmap *) d_bmap; - + + count = 0; + blk[0] = 0; count = get_range(blk ,ds_bmap, buf); while (count){ @@ -738,7 +802,7 @@ while (ds_retval){ #ifdef DEBUG_MAGIC_SCAN printf("try a fragment recover for metablock %ld\n",flag[i]); #endif - blk[1] = block_backward(flag[i] , 12); + blk[1] = block_backward(flag[i] , 13); if (blk[1]){ blk[0] = blk[1]; fragment_flag = flag[i]; @@ -532,8 +532,7 @@ return; } -void get_ind_block_len(char *buf, blk_t *blk, blk_t *last ,blk_t *next, __u64 *p_len){ -// unsigned long long len; +int get_ind_block_len(char *buf, blk_t *blk, blk_t *last ,blk_t *next, __u64 *p_len){ int i = (current_fs->blocksize >> 2)- 1; char *priv_buf = NULL; blk_t block, *p_block; @@ -542,7 +541,7 @@ void get_ind_block_len(char *buf, blk_t *blk, blk_t *last ,blk_t *next, __u64 *p priv_buf = malloc(current_fs->blocksize); if (! priv_buf){ fprintf(stderr,"can not allocate memory\n"); - return ; + return 0; } p_block = (blk_t*)buf; p_block += i; @@ -555,9 +554,10 @@ void get_ind_block_len(char *buf, blk_t *blk, blk_t *last ,blk_t *next, __u64 *p } else break; } - if (io_channel_read_blk ( current_fs->io, block, 1, priv_buf )){ - fprintf(stderr,"ERROR: while read block %10u\n",block); - return ; + if ((block >= current_fs->super->s_blocks_count) || + (ext2fs_test_block_bitmap(bmap,block)) || (io_channel_read_blk ( current_fs->io, block, 1, priv_buf ))){ +// fprintf(stderr,"ERROR: while read block %10u\n",block); + return 0; } *next = (flag) ? 0 : block+1 ; *last = block; @@ -565,13 +565,13 @@ void get_ind_block_len(char *buf, blk_t *blk, blk_t *last ,blk_t *next, __u64 *p *p_len += (i * (current_fs->blocksize)) ; *blk += (i + 1) ; free(priv_buf); -return ; +return 1; } -void get_dind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *p_len){ -// unsigned long long len; +int get_dind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *p_len){ + int ret = 0; int i = (current_fs->blocksize >> 2)- 1; char *priv_buf = NULL; blk_t block, *p_block; @@ -579,7 +579,7 @@ void get_dind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 * priv_buf = malloc(current_fs->blocksize); if (! priv_buf){ fprintf(stderr,"can not allocate memory\n"); - return; + return 0; } p_block = (blk_t*)buf; p_block += i; @@ -591,23 +591,26 @@ void get_dind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 * } else break; } - if (io_channel_read_blk ( current_fs->io, block, 1, priv_buf )){ - fprintf(stderr,"ERROR: while read ind-block %10u\n",block); - return; + if ((block >= current_fs->super->s_blocks_count) || + (ext2fs_test_block_bitmap(bmap,block)) || (io_channel_read_blk ( current_fs->io, block, 1, priv_buf ))){ +// fprintf(stderr,"ERROR: while read ind-block %10u\n",block); + return 0; } - get_ind_block_len(priv_buf, blk, last, next, p_len); - *p_len += (i * current_fs->blocksize * (current_fs->blocksize >>2) ) ; - *next = ( i == ((current_fs->blocksize >> 2)- 1)) ? *last : 0 ; - *blk += ((i * ((current_fs->blocksize >>2) + 1)) + 1) ; + ret = get_ind_block_len(priv_buf, blk, last, next, p_len); + if (ret){ + *p_len += (i * current_fs->blocksize * (current_fs->blocksize >>2) ) ; + *next = ( i == ((current_fs->blocksize >> 2)- 1)) ? *last : 0 ; + *blk += ((i * ((current_fs->blocksize >>2) + 1)) + 1) ; + } free(priv_buf); -return ; +return ret ; } -void get_tind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *p_len){ -// unsigned long long len; +int get_tind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *p_len){ + int ret = 0; int i = (current_fs->blocksize >> 2)- 1; char *priv_buf = NULL; blk_t block, *p_block; @@ -615,7 +618,7 @@ void get_tind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 * priv_buf = malloc(current_fs->blocksize); if (! priv_buf){ fprintf(stderr,"can not allocate memory\n"); - return ; + return 0 ; } p_block = (blk_t*)buf; p_block += i; @@ -627,16 +630,19 @@ void get_tind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 * } else break; } - if (io_channel_read_blk ( current_fs->io, block, 1, priv_buf )){ - fprintf(stderr,"ERROR: while read dind-block %10u\n",block); - return ; + if ((block >= current_fs->super->s_blocks_count) || + (ext2fs_test_block_bitmap(bmap,block)) ||(io_channel_read_blk ( current_fs->io, block, 1, priv_buf ))){ +// fprintf(stderr,"ERROR: while read dind-block %10u\n",block); + return 0; } - get_dind_block_len(priv_buf, blk, last, next,p_len); - *p_len += (i * current_fs->blocksize * (current_fs->blocksize >>2) * (current_fs->blocksize >>2) ) ; - *blk += ((i * ((current_fs->blocksize >>2) + 1) * (current_fs->blocksize >>2)) + 1) ; - *next = 0; + ret = get_dind_block_len(priv_buf, blk, last, next,p_len); + if (ret){ + *p_len += (i * current_fs->blocksize * (current_fs->blocksize >>2) * (current_fs->blocksize >>2) ) ; + *blk += ((i * ((current_fs->blocksize >>2) + 1) * (current_fs->blocksize >>2)) + 1) ; + *next = 0; + } free(priv_buf); -return; +return ret; } |