diff mbox series

[SRU,1/1] ext4: zero out the unused memory region in the extent tree block

Message ID 20190604060845.26027-2-khalid.elmously@canonical.com
State New
Headers show
Series Fix for CVE-2019-11833 | expand

Commit Message

Khalid Elmously June 4, 2019, 6:08 a.m. UTC
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>
---
 fs/ext4/extents.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

Comments

Connor Kuehl June 4, 2019, 4:13 p.m. UTC | #1
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);
>
Thadeu Lima de Souza Cascardo June 24, 2019, 1:11 p.m. UTC | #2
Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
diff mbox series

Patch

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);