Commit 2ca32224 authored by Sriram Rajagopalan's avatar Sriram Rajagopalan Committed by Kleber Sacilotto de Souza

ext4: zero out the unused memory region in the extent tree block

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: default avatarSriram Rajagopalan <sriramr@arista.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org
(cherry picked from commit 592acbf1)
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
Acked-by: default avatarConnor Kuehl <connor.kuehl@canonical.com>
Acked-by: default avatarThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
parent 933dda2d
...@@ -1049,6 +1049,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, ...@@ -1049,6 +1049,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
__le32 border; __le32 border;
ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */ ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */
int err = 0; int err = 0;
size_t ext_size = 0;
/* make decision: where to split? */ /* make decision: where to split? */
/* FIXME: now decision is simplest: at current extent */ /* FIXME: now decision is simplest: at current extent */
...@@ -1140,6 +1141,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, ...@@ -1140,6 +1141,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
le16_add_cpu(&neh->eh_entries, 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); ext4_extent_block_csum_set(inode, neh);
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
unlock_buffer(bh); unlock_buffer(bh);
...@@ -1219,6 +1224,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, ...@@ -1219,6 +1224,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
sizeof(struct ext4_extent_idx) * m); sizeof(struct ext4_extent_idx) * m);
le16_add_cpu(&neh->eh_entries, 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); ext4_extent_block_csum_set(inode, neh);
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
unlock_buffer(bh); unlock_buffer(bh);
...@@ -1284,6 +1294,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, ...@@ -1284,6 +1294,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
ext4_fsblk_t newblock, goal = 0; ext4_fsblk_t newblock, goal = 0;
struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
int err = 0; int err = 0;
size_t ext_size = 0;
/* Try to prepend new index to old one */ /* Try to prepend new index to old one */
if (ext_depth(inode)) if (ext_depth(inode))
...@@ -1309,9 +1320,11 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, ...@@ -1309,9 +1320,11 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
goto out; goto out;
} }
ext_size = sizeof(EXT4_I(inode)->i_data);
/* move top-level index/leaf into new block */ /* move top-level index/leaf into new block */
memmove(bh->b_data, EXT4_I(inode)->i_data, memmove(bh->b_data, EXT4_I(inode)->i_data, ext_size);
sizeof(EXT4_I(inode)->i_data)); /* 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 */ /* set size of new block */
neh = ext_block_hdr(bh); neh = ext_block_hdr(bh);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment