Commit b0336e8d authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Theodore Ts'o

ext4: calculate and verify checksums of directory leaf blocks

Calculate and verify the checksums for directory leaf blocks
(i.e. blocks that only contain actual directory entries).  The
checksum lives in what looks to be an unused directory entry with a 0
name_len at the end of the block.  This scheme is not used for
internal htree nodes because the mechanism in place there only costs
one dx_entry, whereas the "empty" directory entry would cost two
dx_entries.
Signed-off-by: default avatarDarrick J. Wong <djwong@us.ibm.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent dbe89444
...@@ -179,6 +179,18 @@ static int ext4_readdir(struct file *filp, ...@@ -179,6 +179,18 @@ static int ext4_readdir(struct file *filp,
continue; continue;
} }
/* Check the checksum */
if (!buffer_verified(bh) &&
!ext4_dirent_csum_verify(inode,
(struct ext4_dir_entry *)bh->b_data)) {
EXT4_ERROR_FILE(filp, 0, "directory fails checksum "
"at offset %llu",
(unsigned long long)filp->f_pos);
filp->f_pos += sb->s_blocksize - offset;
continue;
}
set_buffer_verified(bh);
revalidate: revalidate:
/* If the dir block has changed since the last call to /* If the dir block has changed since the last call to
* readdir(2), then we might be pointing to an invalid * readdir(2), then we might be pointing to an invalid
......
...@@ -2019,6 +2019,8 @@ extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long); ...@@ -2019,6 +2019,8 @@ extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
extern int ext4_ext_migrate(struct inode *); extern int ext4_ext_migrate(struct inode *);
/* namei.c */ /* namei.c */
extern int ext4_dirent_csum_verify(struct inode *inode,
struct ext4_dir_entry *dirent);
extern int ext4_orphan_add(handle_t *, struct inode *); extern int ext4_orphan_add(handle_t *, struct inode *);
extern int ext4_orphan_del(handle_t *, struct inode *); extern int ext4_orphan_del(handle_t *, struct inode *);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment