diff options
author | Qu Wenruo <quwenruo@cn.fujitsu.com> | 2016-08-30 11:29:32 +0800 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2016-09-05 10:04:24 +0200 |
commit | 245cf06dfaec144fac3423e91d0bbb2b686b5ed1 (patch) | |
tree | 479723a45d39649cd06aaf7953f9ad44d2d7f220 | |
parent | 767ae9e348a667fa4e05e3b1a01630ecaff1f27d (diff) |
btrfs-progs: check: do early check for read_tree_block
Although we have enhanced read_tree_block() from a lot of different
aspects, it lacks the early bytenr/blocksize alignment check.
And the lack of such check can lead to strange use-after-free bugs, due
to the fact that alloc_extent_buffer() will free overlapping extent
buffers, and allocate new eb for the usage.
So we should not allow invalid bytenr/blocksize even passed to
btrfs_find_create_tree_block().
This patch will add such check so we won't trigger use-after-free bug
then.
Reported-by: Lukas Lueg <lukas.lueg@gmail.com>
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r-- | disk-io.c | 18 |
1 files changed, 18 insertions, 0 deletions
@@ -313,11 +313,29 @@ struct extent_buffer* read_tree_block_fs_info( int ret; struct extent_buffer *eb; u64 best_transid = 0; + u32 sectorsize = btrfs_super_sectorsize(fs_info->super_copy); + u32 nodesize = btrfs_super_nodesize(fs_info->super_copy); int mirror_num = 0; int good_mirror = 0; int num_copies; int ignore = 0; + /* + * Don't even try to create tree block for unaligned tree block + * bytenr. + * Such unaligned tree block will free overlapping extent buffer, + * causing use-after-free bugs for fuzzed images. + */ + if (!IS_ALIGNED(bytenr, sectorsize)) { + error("tree block bytenr %llu is not aligned to sectorsize %u", + bytenr, sectorsize); + return ERR_PTR(-EIO); + } + if (!IS_ALIGNED(blocksize, nodesize)) { + error("tree block size %u is not aligned to nodesize %u", + blocksize, nodesize); + return ERR_PTR(-EIO); + } eb = btrfs_find_create_tree_block(fs_info, bytenr, blocksize); if (!eb) return ERR_PTR(-ENOMEM); |