aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSriram Rajagopalan <sriramr@arista.com>2019-05-10 19:28:06 -0400
committerTheodore Ts'o <tytso@mit.edu>2019-05-10 19:28:06 -0400
commit592acbf16821288ecdc4192c47e3774a4c48bb64 (patch)
tree1b196247f70faa977aafc443bf57ecedd4490503
parentdb90f41916cf04c020062f8d8b0385942248283e (diff)
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
-rw-r--r--fs/ext4/extents.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 0f89f5190cd7..f2c62e2a0c98 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1035,6 +1035,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
1035 __le32 border; 1035 __le32 border;
1036 ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */ 1036 ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */
1037 int err = 0; 1037 int err = 0;
1038 size_t ext_size = 0;
1038 1039
1039 /* make decision: where to split? */ 1040 /* make decision: where to split? */
1040 /* FIXME: now decision is simplest: at current extent */ 1041 /* FIXME: now decision is simplest: at current extent */
@@ -1126,6 +1127,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
1126 le16_add_cpu(&neh->eh_entries, m); 1127 le16_add_cpu(&neh->eh_entries, m);
1127 } 1128 }
1128 1129
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);
1129 ext4_extent_block_csum_set(inode, neh); 1134 ext4_extent_block_csum_set(inode, neh);
1130 set_buffer_uptodate(bh); 1135 set_buffer_uptodate(bh);
1131 unlock_buffer(bh); 1136 unlock_buffer(bh);
@@ -1205,6 +1210,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
1205 sizeof(struct ext4_extent_idx) * m); 1210 sizeof(struct ext4_extent_idx) * m);
1206 le16_add_cpu(&neh->eh_entries, m); 1211 le16_add_cpu(&neh->eh_entries, m);
1207 } 1212 }
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);
1208 ext4_extent_block_csum_set(inode, neh); 1218 ext4_extent_block_csum_set(inode, neh);
1209 set_buffer_uptodate(bh); 1219 set_buffer_uptodate(bh);
1210 unlock_buffer(bh); 1220 unlock_buffer(bh);
@@ -1270,6 +1280,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1270 ext4_fsblk_t newblock, goal = 0; 1280 ext4_fsblk_t newblock, goal = 0;
1271 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; 1281 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
1272 int err = 0; 1282 int err = 0;
1283 size_t ext_size = 0;
1273 1284
1274 /* Try to prepend new index to old one */ 1285 /* Try to prepend new index to old one */
1275 if (ext_depth(inode)) 1286 if (ext_depth(inode))
@@ -1295,9 +1306,11 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1295 goto out; 1306 goto out;
1296 } 1307 }
1297 1308
1309 ext_size = sizeof(EXT4_I(inode)->i_data);
1298 /* move top-level index/leaf into new block */ 1310 /* move top-level index/leaf into new block */
1299 memmove(bh->b_data, EXT4_I(inode)->i_data, 1311 memmove(bh->b_data, EXT4_I(inode)->i_data, ext_size);
1300 sizeof(EXT4_I(inode)->i_data)); 1312 /* zero out unused area in the extent block */
1313 memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
1301 1314
1302 /* set size of new block */ 1315 /* set size of new block */
1303 neh = ext_block_hdr(bh); 1316 neh = ext_block_hdr(bh);