From 8910626bca3073b1badecc0a9dcac968dcd1a031 Mon Sep 17 00:00:00 2001 From: Salvatore Bonaccorso Date: Fri, 7 Jun 2019 14:52:20 +0200 Subject: [PATCH] ext4: zero out the unused memory region in the extent tree block (CVE-2019-11833) --- debian/changelog | 2 + ...e-unused-memory-region-in-the-extent.patch | 82 +++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 85 insertions(+) create mode 100644 debian/patches/bugfix/all/ext4-zero-out-the-unused-memory-region-in-the-extent.patch diff --git a/debian/changelog b/debian/changelog index 8fb1e59d3..db44a0722 100644 --- a/debian/changelog +++ b/debian/changelog @@ -16,6 +16,8 @@ linux (4.19.37-4) UNRELEASED; urgency=medium * brcmfmac: assure SSID length from firmware is limited (CVE-2019-9500) * brcmfmac: add subtype check for event handling in data path (CVE-2019-9503) + * ext4: zero out the unused memory region in the extent tree block + (CVE-2019-11833) -- Ben Hutchings Sun, 19 May 2019 00:04:16 +0100 diff --git a/debian/patches/bugfix/all/ext4-zero-out-the-unused-memory-region-in-the-extent.patch b/debian/patches/bugfix/all/ext4-zero-out-the-unused-memory-region-in-the-extent.patch new file mode 100644 index 000000000..05266fb89 --- /dev/null +++ b/debian/patches/bugfix/all/ext4-zero-out-the-unused-memory-region-in-the-extent.patch @@ -0,0 +1,82 @@ +From: Sriram Rajagopalan +Date: Fri, 10 May 2019 19:28:06 -0400 +Subject: ext4: zero out the unused memory region in the extent tree block +Origin: https://git.kernel.org/linus/592acbf16821288ecdc4192c47e3774a4c48bb64 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-11833 + +This commit zeroes out the unused memory region in the buffer_head +corresponding to the extent metablock after writing the extent header +and the corresponding extent node entries. + +This is done to prevent random uninitialized data from getting into +the filesystem when the extent block is synced. + +This fixes CVE-2019-11833. + +Signed-off-by: Sriram Rajagopalan +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +--- + fs/ext4/extents.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 0f89f5190cd7..f2c62e2a0c98 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -1035,6 +1035,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, + __le32 border; + ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */ + int err = 0; ++ size_t ext_size = 0; + + /* make decision: where to split? */ + /* FIXME: now decision is simplest: at current extent */ +@@ -1126,6 +1127,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, + le16_add_cpu(&neh->eh_entries, m); + } + ++ /* zero out unused area in the extent block */ ++ ext_size = sizeof(struct ext4_extent_header) + ++ sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries); ++ memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size); + ext4_extent_block_csum_set(inode, neh); + set_buffer_uptodate(bh); + unlock_buffer(bh); +@@ -1205,6 +1210,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, + sizeof(struct ext4_extent_idx) * m); + le16_add_cpu(&neh->eh_entries, m); + } ++ /* zero out unused area in the extent block */ ++ ext_size = sizeof(struct ext4_extent_header) + ++ (sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries)); ++ memset(bh->b_data + ext_size, 0, ++ inode->i_sb->s_blocksize - ext_size); + ext4_extent_block_csum_set(inode, neh); + set_buffer_uptodate(bh); + unlock_buffer(bh); +@@ -1270,6 +1280,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, + ext4_fsblk_t newblock, goal = 0; + struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; + int err = 0; ++ size_t ext_size = 0; + + /* Try to prepend new index to old one */ + if (ext_depth(inode)) +@@ -1295,9 +1306,11 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, + goto out; + } + ++ ext_size = sizeof(EXT4_I(inode)->i_data); + /* move top-level index/leaf into new block */ +- memmove(bh->b_data, EXT4_I(inode)->i_data, +- sizeof(EXT4_I(inode)->i_data)); ++ memmove(bh->b_data, EXT4_I(inode)->i_data, ext_size); ++ /* zero out unused area in the extent block */ ++ memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size); + + /* set size of new block */ + neh = ext_block_hdr(bh); +-- +2.20.1 + diff --git a/debian/patches/series b/debian/patches/series index 47d1b11eb..6aa59d475 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -214,6 +214,7 @@ bugfix/all/spec/0030-x86-speculation-mds-Fix-documentation-typo.patch bugfix/all/spec/powerpc-64s-include-cpu-header.patch bugfix/all/brcmfmac-assure-SSID-length-from-firmware-is-limited.patch bugfix/all/brcmfmac-add-subtype-check-for-event-handling-in-dat.patch +bugfix/all/ext4-zero-out-the-unused-memory-region-in-the-extent.patch # Fix exported symbol versions bugfix/all/module-disable-matching-missing-version-crc.patch