@@ -3500,6 +3500,9 @@ static struct buffer_head *ext4_get_first_dir_block(handle_t *handle,
35003500 struct buffer_head * bh ;
35013501
35023502 if (!ext4_has_inline_data (inode )) {
3503+ struct ext4_dir_entry_2 * de ;
3504+ unsigned int offset ;
3505+
35033506 /* The first directory block must not be a hole, so
35043507 * treat it as DIRENT_HTREE
35053508 */
@@ -3508,9 +3511,30 @@ static struct buffer_head *ext4_get_first_dir_block(handle_t *handle,
35083511 * retval = PTR_ERR (bh );
35093512 return NULL ;
35103513 }
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+
35143538 return bh ;
35153539 }
35163540
0 commit comments