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