@@ -3454,6 +3454,9 @@ static struct buffer_head *ext4_get_first_dir_block(handle_t *handle,
3454
3454
struct buffer_head * bh ;
3455
3455
3456
3456
if (!ext4_has_inline_data (inode )) {
3457
+ struct ext4_dir_entry_2 * de ;
3458
+ unsigned int offset ;
3459
+
3457
3460
/* The first directory block must not be a hole, so
3458
3461
* treat it as DIRENT_HTREE
3459
3462
*/
@@ -3462,9 +3465,30 @@ static struct buffer_head *ext4_get_first_dir_block(handle_t *handle,
3462
3465
* retval = PTR_ERR (bh );
3463
3466
return NULL ;
3464
3467
}
3465
- * parent_de = ext4_next_entry (
3466
- (struct ext4_dir_entry_2 * )bh -> b_data ,
3467
- inode -> i_sb -> s_blocksize );
3468
+
3469
+ de = (struct ext4_dir_entry_2 * ) bh -> b_data ;
3470
+ if (ext4_check_dir_entry (inode , NULL , de , bh , bh -> b_data ,
3471
+ bh -> b_size , 0 ) ||
3472
+ le32_to_cpu (de -> inode ) != inode -> i_ino ||
3473
+ strcmp ("." , de -> name )) {
3474
+ EXT4_ERROR_INODE (inode , "directory missing '.'" );
3475
+ brelse (bh );
3476
+ * retval = - EFSCORRUPTED ;
3477
+ return NULL ;
3478
+ }
3479
+ offset = ext4_rec_len_from_disk (de -> rec_len ,
3480
+ inode -> i_sb -> s_blocksize );
3481
+ de = ext4_next_entry (de , inode -> i_sb -> s_blocksize );
3482
+ if (ext4_check_dir_entry (inode , NULL , de , bh , bh -> b_data ,
3483
+ bh -> b_size , offset ) ||
3484
+ le32_to_cpu (de -> inode ) == 0 || strcmp (".." , de -> name )) {
3485
+ EXT4_ERROR_INODE (inode , "directory missing '..'" );
3486
+ brelse (bh );
3487
+ * retval = - EFSCORRUPTED ;
3488
+ return NULL ;
3489
+ }
3490
+ * parent_de = de ;
3491
+
3468
3492
return bh ;
3469
3493
}
3470
3494
0 commit comments