e2fsprogs/e2fsck-abort-if-there-is-a-corrupted-directory-block.patch
OBS User rfrohl 904a514d0f Set link to e2fsprogs.13740 via maintenance_release request
Rev SUSE:SLE-12:Update/6 Md5 73812aca01aeecfd4827ba0ea0c83416 2020-01-13 13:12:18 rfrohl None
2020-01-13 13:12:18 +00:00

56 lines
1.9 KiB
Diff

From 8dd73c149f418238f19791f9d666089ef9734dff Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Thu, 19 Dec 2019 19:37:34 -0500
Subject: [PATCH] e2fsck: abort if there is a corrupted directory block
when rehashing
References: bsc#1160571 CVE-2019-5188
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.
Addresses: TALOS-2019-0973
Addresses: CVE-2019-5188
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
---
e2fsck/rehash.c | 9 +++++++++
1 file changed, 9 insertions(+)
Index: e2fsprogs-1.42.11/e2fsck/rehash.c
===================================================================
--- e2fsprogs-1.42.11.orig/e2fsck/rehash.c
+++ e2fsprogs-1.42.11/e2fsck/rehash.c
@@ -129,6 +129,10 @@ static int fill_dir_block(ext2_filsys fs
dir_offset += rec_len;
if (dirent->inode == 0)
continue;
+ if ((dirent->name_len&0xFF) == 0) {
+ fd->err = EXT2_ET_DIR_CORRUPTED;
+ return BLOCK_ABORT;
+ }
if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
(dirent->name[0] == '.'))
continue;
@@ -365,8 +369,13 @@ static int duplicate_search_and_fix(e2fs
fixed++;
continue;
}
- memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
new_len = ent->dir->name_len;
+ if (new_len & 0xFF == 0) {
+ /* should never happen */
+ ext2fs_unmark_valid(fs);
+ continue;
+ }
+ memcpy(new_name, ent->dir->name, new_len & 0xFF);
mutate_name(new_name, &new_len);
for (j=0; j < fd->num_array; j++) {
if ((i==j) ||