Skip to content

Commit 592acbf

Browse files
rsriramrtytso
authored andcommitted
ext4: zero out the unused memory region in the extent tree block
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 <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]> Cc: [email protected]
1 parent db90f41 commit 592acbf

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

fs/ext4/extents.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
10351035
__le32 border;
10361036
ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */
10371037
int err = 0;
1038+
size_t ext_size = 0;
10381039

10391040
/* make decision: where to split? */
10401041
/* FIXME: now decision is simplest: at current extent */
@@ -1126,6 +1127,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
11261127
le16_add_cpu(&neh->eh_entries, m);
11271128
}
11281129

1130+
/* zero out unused area in the extent block */
1131+
ext_size = sizeof(struct ext4_extent_header) +
1132+
sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries);
1133+
memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
11291134
ext4_extent_block_csum_set(inode, neh);
11301135
set_buffer_uptodate(bh);
11311136
unlock_buffer(bh);
@@ -1205,6 +1210,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
12051210
sizeof(struct ext4_extent_idx) * m);
12061211
le16_add_cpu(&neh->eh_entries, m);
12071212
}
1213+
/* zero out unused area in the extent block */
1214+
ext_size = sizeof(struct ext4_extent_header) +
1215+
(sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries));
1216+
memset(bh->b_data + ext_size, 0,
1217+
inode->i_sb->s_blocksize - ext_size);
12081218
ext4_extent_block_csum_set(inode, neh);
12091219
set_buffer_uptodate(bh);
12101220
unlock_buffer(bh);
@@ -1270,6 +1280,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
12701280
ext4_fsblk_t newblock, goal = 0;
12711281
struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
12721282
int err = 0;
1283+
size_t ext_size = 0;
12731284

12741285
/* Try to prepend new index to old one */
12751286
if (ext_depth(inode))
@@ -1295,9 +1306,11 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
12951306
goto out;
12961307
}
12971308

1309+
ext_size = sizeof(EXT4_I(inode)->i_data);
12981310
/* move top-level index/leaf into new block */
1299-
memmove(bh->b_data, EXT4_I(inode)->i_data,
1300-
sizeof(EXT4_I(inode)->i_data));
1311+
memmove(bh->b_data, EXT4_I(inode)->i_data, ext_size);
1312+
/* zero out unused area in the extent block */
1313+
memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
13011314

13021315
/* set size of new block */
13031316
neh = ext_block_hdr(bh);

0 commit comments

Comments
 (0)