@@ -3500,6 +3500,9 @@ static struct buffer_head *ext4_get_first_dir_block(handle_t *handle,
3500
3500
struct buffer_head * bh ;
3501
3501
3502
3502
if (!ext4_has_inline_data (inode )) {
3503
+ struct ext4_dir_entry_2 * de ;
3504
+ unsigned int offset ;
3505
+
3503
3506
/* The first directory block must not be a hole, so
3504
3507
* treat it as DIRENT_HTREE
3505
3508
*/
@@ -3508,9 +3511,30 @@ static struct buffer_head *ext4_get_first_dir_block(handle_t *handle,
3508
3511
* retval = PTR_ERR (bh );
3509
3512
return NULL ;
3510
3513
}
3511
- * parent_de = ext4_next_entry (
3512
- (struct ext4_dir_entry_2 * )bh -> b_data ,
3513
- inode -> i_sb -> s_blocksize );
3514
+
3515
+ de = (struct ext4_dir_entry_2 * ) bh -> b_data ;
3516
+ if (ext4_check_dir_entry (inode , NULL , de , bh , bh -> b_data ,
3517
+ bh -> b_size , 0 ) ||
3518
+ le32_to_cpu (de -> inode ) != inode -> i_ino ||
3519
+ strcmp ("." , de -> name )) {
3520
+ EXT4_ERROR_INODE (inode , "directory missing '.'" );
3521
+ brelse (bh );
3522
+ * retval = - EFSCORRUPTED ;
3523
+ return NULL ;
3524
+ }
3525
+ offset = ext4_rec_len_from_disk (de -> rec_len ,
3526
+ inode -> i_sb -> s_blocksize );
3527
+ de = ext4_next_entry (de , inode -> i_sb -> s_blocksize );
3528
+ if (ext4_check_dir_entry (inode , NULL , de , bh , bh -> b_data ,
3529
+ bh -> b_size , offset ) ||
3530
+ le32_to_cpu (de -> inode ) == 0 || strcmp (".." , de -> name )) {
3531
+ EXT4_ERROR_INODE (inode , "directory missing '..'" );
3532
+ brelse (bh );
3533
+ * retval = - EFSCORRUPTED ;
3534
+ return NULL ;
3535
+ }
3536
+ * parent_de = de ;
3537
+
3514
3538
return bh ;
3515
3539
}
3516
3540
0 commit comments