add patch wait-for-oustanding-dio-during-truncate-in-nojournal-mode
[ext4-patch-queue.git] / zero-out-the-unused-memory-in-the-extent-tree-block
blobe3af70b5525c3dca2ec9066fc3a32e60753575ea
1 ext4: zero out the unused memory region in the extent tree block
3 From: Sriram Rajagopalan <sriramr@arista.com>
5 This commit zeroes out the unused memory region in the buffer_head
6 corresponding to the extent metablock after writing the extent header
7 and the corresponding extent node entries.
9 This is done to prevent random uninitialized data from getting into
10 the filesystem when the extent block is synced.
12 This fixes CVE-2019-11833.
14 Signed-off-by: Sriram Rajagopalan <sriramr@arista.com>
15 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
16 Cc: stable@kernel.org
17 ---
18  fs/ext4/extents.c | 17 +++++++++++++++--
19  1 file changed, 15 insertions(+), 2 deletions(-)
21 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
22 index 0f89f5190cd7..f2c62e2a0c98 100644
23 --- a/fs/ext4/extents.c
24 +++ b/fs/ext4/extents.c
25 @@ -1035,6 +1035,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
26         __le32 border;
27         ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */
28         int err = 0;
29 +       size_t ext_size = 0;
31         /* make decision: where to split? */
32         /* FIXME: now decision is simplest: at current extent */
33 @@ -1126,6 +1127,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
34                 le16_add_cpu(&neh->eh_entries, m);
35         }
37 +       /* zero out unused area in the extent block */
38 +       ext_size = sizeof(struct ext4_extent_header) +
39 +               sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries);
40 +       memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
41         ext4_extent_block_csum_set(inode, neh);
42         set_buffer_uptodate(bh);
43         unlock_buffer(bh);
44 @@ -1205,6 +1210,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
45                                 sizeof(struct ext4_extent_idx) * m);
46                         le16_add_cpu(&neh->eh_entries, m);
47                 }
48 +               /* zero out unused area in the extent block */
49 +               ext_size = sizeof(struct ext4_extent_header) +
50 +                  (sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries));
51 +               memset(bh->b_data + ext_size, 0,
52 +                       inode->i_sb->s_blocksize - ext_size);
53                 ext4_extent_block_csum_set(inode, neh);
54                 set_buffer_uptodate(bh);
55                 unlock_buffer(bh);
56 @@ -1270,6 +1280,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
57         ext4_fsblk_t newblock, goal = 0;
58         struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
59         int err = 0;
60 +       size_t ext_size = 0;
62         /* Try to prepend new index to old one */
63         if (ext_depth(inode))
64 @@ -1295,9 +1306,11 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
65                 goto out;
66         }
68 +       ext_size = sizeof(EXT4_I(inode)->i_data);
69         /* move top-level index/leaf into new block */
70 -       memmove(bh->b_data, EXT4_I(inode)->i_data,
71 -               sizeof(EXT4_I(inode)->i_data));
72 +       memmove(bh->b_data, EXT4_I(inode)->i_data, ext_size);
73 +       /* zero out unused area in the extent block */
74 +       memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
76         /* set size of new block */
77         neh = ext_block_hdr(bh);