e2fsck: abort if there is a corrupted directory block when rehashing 69/294669/1 accepted/tizen_6.0_base accepted/tizen_6.0_base_tool tizen_6.0_base accepted/tizen/6.0/base/20230713.142821 accepted/tizen/6.0/base/tool/20230710.095805 submit/tizen_6.0_base/20230705.092351
authorTheodore Ts'o <tytso@mit.edu>
Fri, 20 Dec 2019 00:37:34 +0000 (19:37 -0500)
committerKrystian Czapiga <k.czapiga@samsung.com>
Thu, 22 Jun 2023 14:38:28 +0000 (16:38 +0200)
In e2fsck pass 3a, when we are rehashing directories, at least in
theory, all of the directories should have had corruptions with
respect to directory entry structure fixed.  However, it's possible
(for example, if the user declined a fix) that we can reach this stage
of processing with a corrupted directory entries.

So check for that case and don't try to process a corrupted directory
block so we don't run into trouble in mutate_name() if there is a
zero-length file name.

Change-Id: I41bc9752d8c0dc72956e39a45d8380b5d9375161
Addresses: TALOS-2019-0973
Addresses: CVE-2019-5188
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Origin: upstream, https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/commit/?id=8dd73c149f418238f19791f9d666089ef9734dff
Signed-off-by: Krystian Czapiga <k.czapiga@samsung.com>
e2fsck/rehash.c

index 22a58f3..a832d1f 100644 (file)
@@ -159,6 +159,10 @@ static int fill_dir_block(ext2_filsys fs,
                dir_offset += rec_len;
                if (dirent->inode == 0)
                        continue;
+               if ((name_len) == 0) {
+                       fd->err = EXT2_ET_DIR_CORRUPTED;
+                       return BLOCK_ABORT;
+               }
                if (!fd->compress && (name_len == 1) &&
                    (dirent->name[0] == '.'))
                        continue;
@@ -398,6 +402,11 @@ static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
                        continue;
                }
                new_len = ext2fs_dirent_name_len(ent->dir);
+               if (new_len == 0) {
+                        /* should never happen */
+                       ext2fs_unmark_valid(fs);
+                       continue;
+               }
                memcpy(new_name, ent->dir->name, new_len);
                mutate_name(new_name, &new_len);
                for (j=0; j < fd->num_array; j++) {