Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <sriramr@arista.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org

authored by

Sriram Rajagopalan and committed by
Theodore Ts'o
592acbf1 db90f419

+15 -2
+15 -2
fs/ext4/extents.c
··· 1035 1035 __le32 border; 1036 1036 ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */ 1037 1037 int err = 0; 1038 + size_t ext_size = 0; 1038 1039 1039 1040 /* make decision: where to split? */ 1040 1041 /* FIXME: now decision is simplest: at current extent */ ··· 1127 1126 le16_add_cpu(&neh->eh_entries, m); 1128 1127 } 1129 1128 1129 + /* zero out unused area in the extent block */ 1130 + ext_size = sizeof(struct ext4_extent_header) + 1131 + sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries); 1132 + memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size); 1130 1133 ext4_extent_block_csum_set(inode, neh); 1131 1134 set_buffer_uptodate(bh); 1132 1135 unlock_buffer(bh); ··· 1210 1205 sizeof(struct ext4_extent_idx) * m); 1211 1206 le16_add_cpu(&neh->eh_entries, m); 1212 1207 } 1208 + /* zero out unused area in the extent block */ 1209 + ext_size = sizeof(struct ext4_extent_header) + 1210 + (sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries)); 1211 + memset(bh->b_data + ext_size, 0, 1212 + inode->i_sb->s_blocksize - ext_size); 1213 1213 ext4_extent_block_csum_set(inode, neh); 1214 1214 set_buffer_uptodate(bh); 1215 1215 unlock_buffer(bh); ··· 1280 1270 ext4_fsblk_t newblock, goal = 0; 1281 1271 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; 1282 1272 int err = 0; 1273 + size_t ext_size = 0; 1283 1274 1284 1275 /* Try to prepend new index to old one */ 1285 1276 if (ext_depth(inode)) ··· 1306 1295 goto out; 1307 1296 } 1308 1297 1298 + ext_size = sizeof(EXT4_I(inode)->i_data); 1309 1299 /* move top-level index/leaf into new block */ 1310 - memmove(bh->b_data, EXT4_I(inode)->i_data, 1311 - sizeof(EXT4_I(inode)->i_data)); 1300 + memmove(bh->b_data, EXT4_I(inode)->i_data, ext_size); 1301 + /* zero out unused area in the extent block */ 1302 + memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size); 1312 1303 1313 1304 /* set size of new block */ 1314 1305 neh = ext_block_hdr(bh);