Version in base suite: 1.44.5-1+deb10u2 Base version: e2fsprogs_1.44.5-1+deb10u2 Target version: e2fsprogs_1.44.5-1+deb10u3 Base file: /srv/ftp-master.debian.org/ftp/pool/main/e/e2fsprogs/e2fsprogs_1.44.5-1+deb10u2.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/e/e2fsprogs/e2fsprogs_1.44.5-1+deb10u3.dsc .gitignore | 1 changelog | 7 patches/e2fsck-abort-if-there-is-a-corrupted-directory-block.patch | 53 +++++++ patches/e2fsck-don-t-try-to-rehash-a-deleted-directory.patch | 47 ++++++ patches/e2fsck-fix-use-after-free-in-calculate_tree.patch | 73 ++++++++++ patches/series | 3 6 files changed, 184 insertions(+) diff -Nru e2fsprogs-1.44.5/debian/.gitignore e2fsprogs-1.44.5/debian/.gitignore --- e2fsprogs-1.44.5/debian/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ e2fsprogs-1.44.5/debian/.gitignore 2020-01-10 01:19:57.000000000 +0000 @@ -0,0 +1 @@ +!patches diff -Nru e2fsprogs-1.44.5/debian/changelog e2fsprogs-1.44.5/debian/changelog --- e2fsprogs-1.44.5/debian/changelog 2019-09-25 17:37:44.000000000 +0000 +++ e2fsprogs-1.44.5/debian/changelog 2020-01-10 01:19:57.000000000 +0000 @@ -1,3 +1,10 @@ +e2fsprogs (1.44.5-1+deb10u3) buster; urgency=medium + + * Fix CVE-2019-5188: potential stack underflow in e2fsck (Closes: #948508) + * Fix use after free in e2fsck (Closes: #948517) + + -- Theodore Y. Ts'o Thu, 09 Jan 2020 20:19:57 -0500 + e2fsprogs (1.44.5-1+deb10u2) buster-security; urgency=high * Fix CVE-2019-5094: potential buffer overrun in e2fsck (Closes: #941139) diff -Nru e2fsprogs-1.44.5/debian/patches/e2fsck-abort-if-there-is-a-corrupted-directory-block.patch e2fsprogs-1.44.5/debian/patches/e2fsck-abort-if-there-is-a-corrupted-directory-block.patch --- e2fsprogs-1.44.5/debian/patches/e2fsck-abort-if-there-is-a-corrupted-directory-block.patch 1970-01-01 00:00:00.000000000 +0000 +++ e2fsprogs-1.44.5/debian/patches/e2fsck-abort-if-there-is-a-corrupted-directory-block.patch 2020-01-10 01:19:57.000000000 +0000 @@ -0,0 +1,53 @@ +From: Theodore Ts'o +Date: Thu, 19 Dec 2019 19:37:34 -0500 +Subject: e2fsck: abort if there is a corrupted directory block when rehashing + +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-Debian-Bug: 948508 +Addresses: TALOS-2019-0973 +Addresses: CVE-2019-5188 +Signed-off-by: Theodore Ts'o +(cherry picked from commit 8dd73c149f418238f19791f9d666089ef9734dff) +--- + e2fsck/rehash.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c +index 7c4ab083..27e1429b 100644 +--- a/e2fsck/rehash.c ++++ b/e2fsck/rehash.c +@@ -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++) { +-- +2.24.1 + diff -Nru e2fsprogs-1.44.5/debian/patches/e2fsck-don-t-try-to-rehash-a-deleted-directory.patch e2fsprogs-1.44.5/debian/patches/e2fsck-don-t-try-to-rehash-a-deleted-directory.patch --- e2fsprogs-1.44.5/debian/patches/e2fsck-don-t-try-to-rehash-a-deleted-directory.patch 1970-01-01 00:00:00.000000000 +0000 +++ e2fsprogs-1.44.5/debian/patches/e2fsck-don-t-try-to-rehash-a-deleted-directory.patch 2020-01-10 01:19:57.000000000 +0000 @@ -0,0 +1,47 @@ +From: Theodore Ts'o +Date: Thu, 19 Dec 2019 19:45:06 -0500 +Subject: e2fsck: don't try to rehash a deleted directory + +If directory has been deleted in pass1[bcd] processing, then we +shouldn't try to rehash the directory in pass 3a when we try to +rehash/reoptimize directories. + +Addresses-Debian-Bug: 948508 +Signed-off-by: Theodore Ts'o +(cherry picked from commit 71ba13755337e19c9a826dfc874562a36e1b24d3) +--- + e2fsck/pass1b.c | 4 ++++ + e2fsck/rehash.c | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c +index 5693b9cf..bca701ca 100644 +--- a/e2fsck/pass1b.c ++++ b/e2fsck/pass1b.c +@@ -705,6 +705,10 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino, + fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); + if (ctx->inode_bad_map) + ext2fs_unmark_inode_bitmap2(ctx->inode_bad_map, ino); ++ if (ctx->inode_reg_map) ++ ext2fs_unmark_inode_bitmap2(ctx->inode_reg_map, ino); ++ ext2fs_unmark_inode_bitmap2(ctx->inode_dir_map, ino); ++ ext2fs_unmark_inode_bitmap2(ctx->inode_used_map, ino); + ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(dp->inode.i_mode)); + quota_data_sub(ctx->qctx, &dp->inode, ino, + pb.dup_blocks * fs->blocksize); +diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c +index 27e1429b..0a5888a9 100644 +--- a/e2fsck/rehash.c ++++ b/e2fsck/rehash.c +@@ -1024,6 +1024,8 @@ void e2fsck_rehash_directories(e2fsck_t ctx) + if (!ext2fs_u32_list_iterate(iter, &ino)) + break; + } ++ if (!ext2fs_test_inode_bitmap2(ctx->inode_dir_map, ino)) ++ continue; + + pctx.dir = ino; + if (first) { +-- +2.24.1 + diff -Nru e2fsprogs-1.44.5/debian/patches/e2fsck-fix-use-after-free-in-calculate_tree.patch e2fsprogs-1.44.5/debian/patches/e2fsck-fix-use-after-free-in-calculate_tree.patch --- e2fsprogs-1.44.5/debian/patches/e2fsck-fix-use-after-free-in-calculate_tree.patch 1970-01-01 00:00:00.000000000 +0000 +++ e2fsprogs-1.44.5/debian/patches/e2fsck-fix-use-after-free-in-calculate_tree.patch 2020-01-10 01:19:57.000000000 +0000 @@ -0,0 +1,73 @@ +From: Wang Shilong +Date: Mon, 30 Dec 2019 19:52:39 -0500 +Subject: e2fsck: fix use after free in calculate_tree() + +The problem is alloc_blocks() will call get_next_block() which might +reallocate outdir->buf, and memory address could be changed after +this. To fix this, pointers that point into outdir->buf, such as +int_limit and root need to be recaulated based on the new starting +address of outdir->buf. + +[ Changed to correctly recalculate int_limit, and to optimize how we + reallocate outdir->buf. -TYT ] + +Addresses-Debian-Bug: 948517 +Signed-off-by: Wang Shilong +Signed-off-by: Theodore Ts'o +(cherry picked from commit 101e73e99ccafa0403fcb27dd7413033b587ca01) +--- + e2fsck/rehash.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c +index 0a5888a9..2574e151 100644 +--- a/e2fsck/rehash.c ++++ b/e2fsck/rehash.c +@@ -295,7 +295,11 @@ static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir, + errcode_t retval; + + if (outdir->num >= outdir->max) { +- retval = alloc_size_dir(fs, outdir, outdir->max + 50); ++ int increment = outdir->max / 10; ++ ++ if (increment < 50) ++ increment = 50; ++ retval = alloc_size_dir(fs, outdir, outdir->max + increment); + if (retval) + return retval; + } +@@ -637,6 +641,9 @@ static int alloc_blocks(ext2_filsys fs, + if (retval) + return retval; + ++ /* outdir->buf might be reallocated */ ++ *prev_ent = (struct ext2_dx_entry *) (outdir->buf + *prev_offset); ++ + *next_ent = set_int_node(fs, block_start); + *limit = (struct ext2_dx_countlimit *)(*next_ent); + if (next_offset) +@@ -726,6 +733,9 @@ static errcode_t calculate_tree(ext2_filsys fs, + return retval; + } + if (c3 == 0) { ++ int delta1 = (char *)int_limit - outdir->buf; ++ int delta2 = (char *)root - outdir->buf; ++ + retval = alloc_blocks(fs, &limit, &int_ent, + &dx_ent, &int_offset, + NULL, outdir, i, &c2, +@@ -733,6 +743,11 @@ static errcode_t calculate_tree(ext2_filsys fs, + if (retval) + return retval; + ++ /* outdir->buf might be reallocated */ ++ int_limit = (struct ext2_dx_countlimit *) ++ (outdir->buf + delta1); ++ root = (struct ext2_dx_entry *) ++ (outdir->buf + delta2); + } + dx_ent->block = ext2fs_cpu_to_le32(i); + if (c3 != limit->limit) +-- +2.24.1 + diff -Nru e2fsprogs-1.44.5/debian/patches/series e2fsprogs-1.44.5/debian/patches/series --- e2fsprogs-1.44.5/debian/patches/series 2019-09-25 17:37:44.000000000 +0000 +++ e2fsprogs-1.44.5/debian/patches/series 2020-01-10 01:19:57.000000000 +0000 @@ -1,2 +1,5 @@ revert-e4defrag-use-64-bit-counters-to-t.patch libsupport-add-checks-to-prevent-buffer-.patch +e2fsck-abort-if-there-is-a-corrupted-directory-block.patch +e2fsck-don-t-try-to-rehash-a-deleted-directory.patch +e2fsck-fix-use-after-free-in-calculate_tree.patch