Message ID | 20190604060845.26027-2-khalid.elmously@canonical.com |
---|---|
State | New |
Headers | show |
Series | Fix for CVE-2019-11833 | expand |
On 6/3/19 11:08 PM, Khalid Elmously wrote: > From: Sriram Rajagopalan <sriramr@arista.com> > > 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 <sriramr@arista.com> > Signed-off-by: Theodore Ts'o <tytso@mit.edu> > Cc: stable@kernel.org > (cherry picked from commit 592acbf16821288ecdc4192c47e3774a4c48bb64) > Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com> Acked-by: Connor Kuehl <connor.kuehl@canonical.com> > --- > 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 5592b7726241..01f44364c547 100644 > --- a/fs/ext4/extents.c > +++ b/fs/ext4/extents.c > @@ -1047,6 +1047,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 */ > @@ -1138,6 +1139,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); > @@ -1217,6 +1222,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); > @@ -1282,6 +1292,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)) > @@ -1307,9 +1318,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); >
Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 5592b7726241..01f44364c547 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -1047,6 +1047,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 */ @@ -1138,6 +1139,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); @@ -1217,6 +1222,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); @@ -1282,6 +1292,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)) @@ -1307,9 +1318,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);