| From: Jan Kara <jack@suse.cz> |
| Date: Mon, 2 Dec 2019 18:02:13 +0100 |
| Subject: ext4: check for directory entries too close to block end |
| |
| commit 109ba779d6cca2d519c5dd624a3276d03e21948e upstream. |
| |
| ext4_check_dir_entry() currently does not catch a case when a directory |
| entry ends so close to the block end that the header of the next |
| directory entry would not fit in the remaining space. This can lead to |
| directory iteration code trying to access address beyond end of current |
| buffer head leading to oops. |
| |
| Signed-off-by: Jan Kara <jack@suse.cz> |
| Link: https://lore.kernel.org/r/20191202170213.4761-3-jack@suse.cz |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| fs/ext4/dir.c | 5 +++++ |
| 1 file changed, 5 insertions(+) |
| |
| --- a/fs/ext4/dir.c |
| +++ b/fs/ext4/dir.c |
| @@ -78,6 +78,11 @@ int __ext4_check_dir_entry(const char *f |
| error_msg = "rec_len is too small for name_len"; |
| else if (unlikely(((char *) de - buf) + rlen > size)) |
| error_msg = "directory entry overrun"; |
| + else if (unlikely(((char *) de - buf) + rlen > |
| + size - EXT4_DIR_REC_LEN(1) && |
| + ((char *) de - buf) + rlen != size)) { |
| + error_msg = "directory entry too close to block end"; |
| + } |
| else if (unlikely(le32_to_cpu(de->inode) > |
| le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count))) |
| error_msg = "inode out of bounds"; |