]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
libext2fs: make ext2fs_dirent_has_tail() more strict
authorTheodore Ts'o <tytso@mit.edu>
Sun, 15 Mar 2020 03:24:39 +0000 (23:24 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 15 Mar 2020 03:24:39 +0000 (23:24 -0400)
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>
lib/ext2fs/csum.c
tests/f_dir_bad_csum/expect.1
tests/f_rebuild_csum_rootdir/expect.1
tests/f_resize_inode_meta_bg/expect.1

index 9823613760a94389028c70e2618fd6f1f1e68bde..a717258079ae10f740374fba1e3f3f014f469f20 100644 (file)
@@ -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,
index 94e72daab05c4397f41e13cbf3d306537d368895..2c684fe6249d9644ee92700a8ac0c8099b0c7679 100644 (file)
@@ -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
 
index 4df58f9133f79e8a99d5ef0ce3ece9e2461fceea..bab07e0528a163143fbce5664d9e1da8df29bc51 100644 (file)
@@ -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
 
index 12055fc79f8d14b55dc13a3a18e1227b9d21c18c..c733c18d96a78a5f518deaac944a349ebc7c16e4 100644 (file)
@@ -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