aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2020-03-14 23:24:39 -0400
committerTheodore Ts'o <tytso@mit.edu>2020-03-14 23:24:39 -0400
commiteb88b751745b5e6b39ddfa2196b5efa9a25535a9 (patch)
tree9c8304e6d7aaa260ee7e80eedc6d542049d85a28
parent6e315c931fdbce55e76bfbdb8f18fa9e59ca48a2 (diff)
downloade2fsprogs-eb88b751745b5e6b39ddfa2196b5efa9a25535a9.tar.gz
libext2fs: make ext2fs_dirent_has_tail() more strict
Previously ext2fs_dirent_has_tail() would return true if the directory was corrupted. If the directory is corrupted, then by definition it doesn't have a valid checksum tail. (This fixes a big-endian failure on the master branch.) Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--lib/ext2fs/csum.c11
-rw-r--r--tests/f_dir_bad_csum/expect.18
-rw-r--r--tests/f_rebuild_csum_rootdir/expect.13
-rw-r--r--tests/f_resize_inode_meta_bg/expect.19
4 files changed, 14 insertions, 17 deletions
diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
index 982361376..a71725807 100644
--- a/lib/ext2fs/csum.c
+++ b/lib/ext2fs/csum.c
@@ -267,13 +267,15 @@ static errcode_t __get_dirent_tail(ext2_filsys fs,
top = EXT2_DIRENT_TAIL(dirent, fs->blocksize);
rec_len = translate(d->rec_len);
- while (rec_len && !(rec_len & 0x3)) {
+ while ((void *) d < top) {
+ if ((rec_len < 8) || (rec_len & 0x03))
+ return EXT2_ET_DIR_CORRUPTED;
d = (struct ext2_dir_entry *)(((char *)d) + rec_len);
- if ((void *)d >= top)
- break;
rec_len = translate(d->rec_len);
}
+ if ((void *)d > ((void *)dirent + fs->blocksize))
+ return EXT2_ET_DIR_CORRUPTED;
if (d != top)
return EXT2_ET_DIR_NO_SPACE_FOR_CSUM;
@@ -290,7 +292,8 @@ static errcode_t __get_dirent_tail(ext2_filsys fs,
int ext2fs_dirent_has_tail(ext2_filsys fs, struct ext2_dir_entry *dirent)
{
- return __get_dirent_tail(fs, dirent, NULL, 0) == 0;
+ return __get_dirent_tail(fs, dirent, NULL, 0) !=
+ EXT2_ET_DIR_NO_SPACE_FOR_CSUM;
}
static errcode_t ext2fs_dirent_csum(ext2_filsys fs, ext2_ino_t inum,
diff --git a/tests/f_dir_bad_csum/expect.1 b/tests/f_dir_bad_csum/expect.1
index 94e72daab..2c684fe62 100644
--- a/tests/f_dir_bad_csum/expect.1
+++ b/tests/f_dir_bad_csum/expect.1
@@ -9,21 +9,15 @@ Fix? yes
Directory inode 14, block #0, offset 0: directory has no checksum.
Fix? yes
-Directory inode 15, block #0, offset 0: directory has no checksum.
-Fix? yes
-
Directory inode 15, block #0, offset 1000: directory corrupted
Salvage? yes
-Directory inode 16, block #0, offset 0: directory has no checksum.
+Entry '' in ??? (15) has rec_len of 0, should be 12.
Fix? yes
Directory inode 16, block #0, offset 12: directory corrupted
Salvage? yes
-Directory inode 17, block #0, offset 0: directory has no checksum.
-Fix? yes
-
Directory inode 17, block #0, offset 0: directory corrupted
Salvage? yes
diff --git a/tests/f_rebuild_csum_rootdir/expect.1 b/tests/f_rebuild_csum_rootdir/expect.1
index 4df58f913..bab07e052 100644
--- a/tests/f_rebuild_csum_rootdir/expect.1
+++ b/tests/f_rebuild_csum_rootdir/expect.1
@@ -1,8 +1,5 @@
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
-Directory inode 2, block #0, offset 0: directory has no checksum.
-Fix? yes
-
Directory inode 2, block #0, offset 0: directory corrupted
Salvage? yes
diff --git a/tests/f_resize_inode_meta_bg/expect.1 b/tests/f_resize_inode_meta_bg/expect.1
index 12055fc79..c733c18d9 100644
--- a/tests/f_resize_inode_meta_bg/expect.1
+++ b/tests/f_resize_inode_meta_bg/expect.1
@@ -5,9 +5,6 @@ Resize_inode not enabled, but the resize inode is non-zero. Clear? yes
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
-Directory inode 2, block #0, offset 0: directory has no checksum.
-Fix? yes
-
First entry '' (inode=348) in directory inode 2 (???) should be '.'
Fix? yes
@@ -19,6 +16,9 @@ Setting filetype for entry '..' in ??? (2) to 2.
Directory inode 2, block #0, offset 860: directory corrupted
Salvage? yes
+Entry '' in ??? (2) has rec_len of 0, should be 12.
+Fix? yes
+
Directory inode 11, block #0, offset 0: directory corrupted
Salvage? yes
@@ -42,6 +42,9 @@ Clear? yes
Directory inode 11, block #3, offset 864: directory corrupted
Salvage? yes
+Entry '' in ??? (11) has rec_len of 0, should be 12.
+Fix? yes
+
Pass 3: Checking directory connectivity
'..' in / (2) is <The NULL inode> (0), should be / (2).
Fix? yes