diff -Nru e2fsprogs-1.42.9/debian/changelog e2fsprogs-1.42.9/debian/changelog --- e2fsprogs-1.42.9/debian/changelog 2014-02-19 11:19:03.000000000 +0000 +++ e2fsprogs-1.42.9/debian/changelog 2015-09-01 12:08:12.000000000 +0000 @@ -1,3 +1,22 @@ +e2fsprogs (1.42.9-3ubuntu1.3) trusty; urgency=medium + + * fix rule-violating lblk->pblk mappings on bigalloc filesystems (LP: #1321418) + + -- Seyeong Kim Tue, 01 Sep 2015 07:08:12 -0500 + +e2fsprogs (1.42.9-3ubuntu1.2) trusty-security; urgency=medium + + * SECURITY UPDATE: heap overflow via block group descriptor information + - debian/patches/CVE-2015-0247.patch: limit first_meta_bg in + lib/ext2fs/closefs.c, lib/ext2fs/openfs.c. + - CVE-2015-0247 + * SECURITY UPDATE: buffer overflow in closefs() + - debian/patches/CVE-2015-1572.patch: properly check against + fs->desc_blocks in lib/ext2fs/closefs.c. + - CVE-2015-1572 + + -- Marc Deslauriers Mon, 16 Feb 2015 13:44:13 -0500 + e2fsprogs (1.42.9-3ubuntu1) trusty; urgency=medium * Merge from Debian unstable, remainging changes: diff -Nru e2fsprogs-1.42.9/debian/patches/CVE-2015-0247.patch e2fsprogs-1.42.9/debian/patches/CVE-2015-0247.patch --- e2fsprogs-1.42.9/debian/patches/CVE-2015-0247.patch 1970-01-01 00:00:00.000000000 +0000 +++ e2fsprogs-1.42.9/debian/patches/CVE-2015-0247.patch 2015-02-13 20:05:28.000000000 +0000 @@ -0,0 +1,54 @@ +From f66e6ce4446738c2c7f43d41988a3eb73347e2f5 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sat, 9 Aug 2014 12:24:54 -0400 +Subject: libext2fs: avoid buffer overflow if s_first_meta_bg is too big + +If s_first_meta_bg is greater than the of number block group +descriptor blocks, then reading or writing the block group descriptors +will end up overruning the memory buffer allocated for the +descriptors. Fix this by limiting first_meta_bg to no more than +fs->desc_blocks. This doesn't correct the bad s_first_meta_bg value, +but it avoids causing the e2fsprogs userspace programs from +potentially crashing. + +Signed-off-by: Theodore Ts'o + +diff --git a/lib/ext2fs/closefs.c b/lib/ext2fs/closefs.c +index 4599eef..1f99113 100644 +--- a/lib/ext2fs/closefs.c ++++ b/lib/ext2fs/closefs.c +@@ -344,9 +344,11 @@ errcode_t ext2fs_flush2(ext2_filsys fs, int flags) + * superblocks and group descriptors. + */ + group_ptr = (char *) group_shadow; +- if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ++ if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) { + old_desc_blocks = fs->super->s_first_meta_bg; +- else ++ if (old_desc_blocks > fs->super->s_first_meta_bg) ++ old_desc_blocks = fs->desc_blocks; ++ } else + old_desc_blocks = fs->desc_blocks; + + ext2fs_numeric_progress_init(fs, &progress, NULL, +diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c +index a1a3517..ba501e6 100644 +--- a/lib/ext2fs/openfs.c ++++ b/lib/ext2fs/openfs.c +@@ -378,9 +378,11 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, + #ifdef WORDS_BIGENDIAN + groups_per_block = EXT2_DESC_PER_BLOCK(fs->super); + #endif +- if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ++ if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) { + first_meta_bg = fs->super->s_first_meta_bg; +- else ++ if (first_meta_bg > fs->desc_blocks) ++ first_meta_bg = fs->desc_blocks; ++ } else + first_meta_bg = fs->desc_blocks; + if (first_meta_bg) { + retval = io_channel_read_blk(fs->io, group_block + +-- +cgit v0.10.2 + diff -Nru e2fsprogs-1.42.9/debian/patches/CVE-2015-1572.patch e2fsprogs-1.42.9/debian/patches/CVE-2015-1572.patch --- e2fsprogs-1.42.9/debian/patches/CVE-2015-1572.patch 1970-01-01 00:00:00.000000000 +0000 +++ e2fsprogs-1.42.9/debian/patches/CVE-2015-1572.patch 2015-02-16 18:44:08.000000000 +0000 @@ -0,0 +1,53 @@ +From 49d0fe2a14f2a23da2fe299643379b8c1d37df73 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Fri, 6 Feb 2015 12:46:39 -0500 +Subject: libext2fs: fix potential buffer overflow in closefs() + +The bug fix in f66e6ce4446: "libext2fs: avoid buffer overflow if +s_first_meta_bg is too big" had a typo in the fix for +ext2fs_closefs(). In practice most of the security exposure was from +the openfs path, since this meant if there was a carefully crafted +file system, buffer overrun would be triggered when the file system was +opened. + +However, if corrupted file system didn't trip over some corruption +check, and then the file system was modified via tune2fs or debugfs, +such that the superblock was marked dirty and then written out via the +closefs() path, it's possible that the buffer overrun could be +triggered when the file system is closed. + +Also clear up a signed vs unsigned warning while we're at it. + +Thanks to Nick Kralevich for asking me to look at +compiler warning in the code in question, which led me to notice the +bug in f66e6ce4446. + +Addresses: CVE-2015-1572 + +Signed-off-by: Theodore Ts'o + +diff --git a/lib/ext2fs/closefs.c b/lib/ext2fs/closefs.c +index 1f99113..ab5b2fb 100644 +--- a/lib/ext2fs/closefs.c ++++ b/lib/ext2fs/closefs.c +@@ -287,7 +287,7 @@ errcode_t ext2fs_flush2(ext2_filsys fs, int flags) + dgrp_t j; + #endif + char *group_ptr; +- int old_desc_blocks; ++ blk64_t old_desc_blocks; + struct ext2fs_numeric_progress_struct progress; + + EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); +@@ -346,7 +346,7 @@ errcode_t ext2fs_flush2(ext2_filsys fs, int flags) + group_ptr = (char *) group_shadow; + if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) { + old_desc_blocks = fs->super->s_first_meta_bg; +- if (old_desc_blocks > fs->super->s_first_meta_bg) ++ if (old_desc_blocks > fs->desc_blocks) + old_desc_blocks = fs->desc_blocks; + } else + old_desc_blocks = fs->desc_blocks; +-- +cgit v0.10.2 + diff -Nru e2fsprogs-1.42.9/debian/patches/fix-multiply-claimed.patch e2fsprogs-1.42.9/debian/patches/fix-multiply-claimed.patch --- e2fsprogs-1.42.9/debian/patches/fix-multiply-claimed.patch 1970-01-01 00:00:00.000000000 +0000 +++ e2fsprogs-1.42.9/debian/patches/fix-multiply-claimed.patch 2015-09-01 12:08:10.000000000 +0000 @@ -0,0 +1,243 @@ +Description: fix rule-violating lblk->pblk mappings on bigalloc filesystems + + As far as I can tell, logical block mappings on a bigalloc filesystem are + supposed to follow a few constraints: + + * The logical cluster offset must match the physical cluster offset. + * A logical cluster may not map to multiple physical clusters. + + Since the multiply-claimed block recovery code can be used to fix these + problems, teach e2fsck to find these transgressions and fix them. + +Author: Darrick J. Wong +Origin: , https://kernel.googlesource.com/pub/scm/fs/ext2/e2fsprogs/+/9a1d614df217c02ea6b2cb0072fccfe706aea111 +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/e2fsprogs/+bug/1321418 +Last-Update: Fri Jul 25 17:34:04 2014 -0700 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: e2fsprogs-1.42.9/e2fsck/pass1.c +=================================================================== +--- e2fsprogs-1.42.9.orig/e2fsck/pass1.c 2015-08-28 05:53:32.000000000 +0000 ++++ e2fsprogs-1.42.9/e2fsck/pass1.c 2015-08-28 06:18:19.810921999 +0000 +@@ -1760,6 +1760,40 @@ + e2fsck_write_inode(ctx, ino, inode, source); + } + ++/* ++ * Use the multiple-blocks reclamation code to fix alignment problems in ++ * a bigalloc filesystem. We want a logical cluster to map to *only* one ++ * physical cluster, and we want the block offsets within that cluster to ++ * line up. ++ */ ++static int has_unaligned_cluster_map(e2fsck_t ctx, ++ blk64_t last_pblk, e2_blkcnt_t last_lblk, ++ blk64_t pblk, blk64_t lblk) ++{ ++ blk64_t cluster_mask; ++ ++ if (!ctx->fs->cluster_ratio_bits) ++ return 0; ++ cluster_mask = EXT2FS_CLUSTER_MASK(ctx->fs); ++ ++ /* ++ * If the block in the logical cluster doesn't align with the block in ++ * the physical cluster... ++ */ ++ if ((lblk & cluster_mask) != (pblk & cluster_mask)) ++ return 1; ++ ++ /* ++ * If we cross a physical cluster boundary within a logical cluster... ++ */ ++ if (last_pblk && (lblk & cluster_mask) != 0 && ++ EXT2FS_B2C(ctx->fs, lblk) == EXT2FS_B2C(ctx->fs, last_lblk) && ++ EXT2FS_B2C(ctx->fs, pblk) != EXT2FS_B2C(ctx->fs, last_pblk)) ++ return 1; ++ ++ return 0; ++} ++ + static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx, + struct process_block_struct *pb, + blk64_t start_block, blk64_t end_block, +@@ -1923,6 +1957,16 @@ + pb->num_blocks++; + } + ++ if (has_unaligned_cluster_map(ctx, pb->previous_block, ++ pb->last_block, blk, ++ blockcnt)) { ++ pctx->blk = blockcnt; ++ pctx->blk2 = blk; ++ fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx); ++ mark_block_used(ctx, blk); ++ mark_block_used(ctx, blk); ++ } ++ pb->last_block = blockcnt; + pb->previous_block = blk; + + if (is_dir) { +@@ -2374,6 +2418,13 @@ + ((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) { + mark_block_used(ctx, blk); + p->num_blocks++; ++ } else if (has_unaligned_cluster_map(ctx, p->previous_block, ++ p->last_block, blk, blockcnt)) { ++ pctx->blk = blockcnt; ++ pctx->blk2 = blk; ++ fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx); ++ mark_block_used(ctx, blk); ++ mark_block_used(ctx, blk); + } + if (blockcnt >= 0) + p->last_block = blockcnt; +Index: e2fsprogs-1.42.9/e2fsck/pass1b.c +=================================================================== +--- e2fsprogs-1.42.9.orig/e2fsck/pass1b.c 2013-12-29 04:18:02.000000000 +0000 ++++ e2fsprogs-1.42.9/e2fsck/pass1b.c 2015-08-28 06:24:24.526921999 +0000 +@@ -261,7 +261,7 @@ + e2fsck_t ctx; + ext2_ino_t ino; + int dup_blocks; +- blk64_t cur_cluster; ++ blk64_t cur_cluster, phys_cluster; + struct ext2_inode *inode; + struct problem_context *pctx; + }; +@@ -314,6 +314,7 @@ + pb.dup_blocks = 0; + pb.inode = &inode; + pb.cur_cluster = ~0; ++ pb.phys_cluster = ~0; + + if (ext2fs_inode_has_valid_blocks2(fs, &inode) || + (ino == EXT2_BAD_INO)) +@@ -350,13 +351,14 @@ + { + struct process_block_struct *p; + e2fsck_t ctx; +- blk64_t lc; ++ blk64_t lc, pc; + + if (HOLE_BLKADDR(*block_nr)) + return 0; + p = (struct process_block_struct *) priv_data; + ctx = p->ctx; + lc = EXT2FS_B2C(fs, blockcnt); ++ pc = EXT2FS_B2C(fs, *block_nr); + + if (!ext2fs_test_block_bitmap2(ctx->block_dup_map, *block_nr)) + goto finish; +@@ -369,11 +371,19 @@ + p->dup_blocks++; + ext2fs_mark_inode_bitmap2(inode_dup_map, p->ino); + +- if (lc != p->cur_cluster) ++ /* ++ * Qualifications for submitting a block for duplicate processing: ++ * It's an extent/indirect block (and has a negative logical offset); ++ * we've crossed a logical cluster boundary; or the physical cluster ++ * suddenly changed, which indicates that blocks in a logical cluster ++ * are mapped to multiple physical clusters. ++ */ ++ if (blockcnt < 0 || lc != p->cur_cluster || pc != p->phys_cluster) + add_dupe(ctx, p->ino, EXT2FS_B2C(fs, *block_nr), p->inode); + + finish: + p->cur_cluster = lc; ++ p->phys_cluster = pc; + return 0; + } + +@@ -543,7 +553,11 @@ + pctx.dir = t->dir; + fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx); + } +- if (file_ok) { ++ /* ++ * Even if the file shares blocks with itself, we still need to ++ * clone the blocks. ++ */ ++ if (file_ok && (meta_data ? shared_len+1 : shared_len) != 0) { + fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx); + continue; + } +@@ -687,9 +701,10 @@ + errcode_t errcode; + blk64_t dup_cluster; + blk64_t alloc_block; +- ext2_ino_t dir; ++ ext2_ino_t dir, ino; + char *buf; + e2fsck_t ctx; ++ struct ext2_inode *inode; + }; + + static int clone_file_block(ext2_filsys fs, +@@ -737,13 +752,26 @@ + decrement_badcount(ctx, *block_nr, p); + + cs->dup_cluster = c; +- ++ /* ++ * Let's try an implied cluster allocation. If we get the same ++ * cluster back, then we need to find a new block; otherwise, ++ * we're merely fixing the problem of one logical cluster being ++ * mapped to multiple physical clusters. ++ */ ++ new_block = 0; ++ retval = ext2fs_map_cluster_block(fs, cs->ino, cs->inode, ++ blockcnt, &new_block); ++ if (retval == 0 && new_block != 0 && ++ EXT2FS_B2C(ctx->fs, new_block) != ++ EXT2FS_B2C(ctx->fs, *block_nr)) ++ goto cluster_alloc_ok; + retval = ext2fs_new_block2(fs, 0, ctx->block_found_map, + &new_block); + if (retval) { + cs->errcode = retval; + return BLOCK_ABORT; + } ++cluster_alloc_ok: + cs->alloc_block = new_block; + + got_block: +@@ -798,6 +826,8 @@ + cs.dup_cluster = ~0; + cs.alloc_block = 0; + cs.ctx = ctx; ++ cs.ino = ino; ++ cs.inode = &dp->inode; + retval = ext2fs_get_mem(fs->blocksize, &cs.buf); + if (retval) + return retval; +Index: e2fsprogs-1.42.9/e2fsck/problem.c +=================================================================== +--- e2fsprogs-1.42.9.orig/e2fsck/problem.c 2015-08-28 05:53:32.000000000 +0000 ++++ e2fsprogs-1.42.9/e2fsck/problem.c 2015-08-28 06:26:29.050921999 +0000 +@@ -966,6 +966,10 @@ + N_("@i %i, end of extent exceeds allowed value\n\t(logical @b %c, physical @b %b, len %N)\n"), + PROMPT_CLEAR, 0 }, + ++ /* Inode logical block (physical block ) is misaligned. */ ++ { PR_1_MISALIGNED_CLUSTER, ++ N_("@i %i logical @b %b (physical @b %c) violates cluster allocation rules.\nWill fix in pass 1B.\n"), ++ PROMPT_NONE, 0 }, + + /* Pass 1b errors */ + +Index: e2fsprogs-1.42.9/e2fsck/problem.h +=================================================================== +--- e2fsprogs-1.42.9.orig/e2fsck/problem.h 2013-12-29 04:18:02.000000000 +0000 ++++ e2fsprogs-1.42.9/e2fsck/problem.h 2015-08-28 06:26:58.334921999 +0000 +@@ -565,6 +565,10 @@ + #define PR_1_EXTENT_INDEX_START_INVALID 0x01006D + + #define PR_1_EXTENT_END_OUT_OF_BOUNDS 0x01006E ++ ++/* Inode logical block is misaligned */ ++#define PR_1_MISALIGNED_CLUSTER 0x010074 ++ + /* + * Pass 1b errors + */ diff -Nru e2fsprogs-1.42.9/debian/patches/series e2fsprogs-1.42.9/debian/patches/series --- e2fsprogs-1.42.9/debian/patches/series 2014-02-19 11:16:15.000000000 +0000 +++ e2fsprogs-1.42.9/debian/patches/series 2015-09-01 12:08:10.000000000 +0000 @@ -2,3 +2,6 @@ fix-printf-format-type-match fix-debugfs-block-parse-error-reporting update-to-git-f3ff319f79 +CVE-2015-0247.patch +CVE-2015-1572.patch +fix-multiply-claimed.patch