From 92c5594969caad29ffd333441ac85bdaa4b7ac3e Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 29 Jan 2019 23:07:27 -0500 Subject: [PATCH] libext2fs: add checks for block number wrapping for bitmap range functions This fixes potential seg faults when opening a fuzzed file system with block group descriptors containing a bogus inode table location. Google-Bug-Id: 119929050 Signed-off-by: Theodore Ts'o --- lib/ext2fs/gen_bitmap.c | 12 ++++++++---- lib/ext2fs/gen_bitmap64.c | 18 ++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/ext2fs/gen_bitmap.c b/lib/ext2fs/gen_bitmap.c index d0061b822..674baa3e2 100644 --- a/lib/ext2fs/gen_bitmap.c +++ b/lib/ext2fs/gen_bitmap.c @@ -554,7 +554,8 @@ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap, blk_t block, int num) { EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP); - if ((block < bitmap->start) || (block+num-1 > bitmap->real_end)) { + if ((block < bitmap->start) || (block > bitmap->real_end) || + (block+num-1 > bitmap->real_end)) { ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, block, bitmap->description); return 0; @@ -567,7 +568,8 @@ int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap, ext2_ino_t inode, int num) { EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP); - if ((inode < bitmap->start) || (inode+num-1 > bitmap->real_end)) { + if ((inode < bitmap->start) || (inode > bitmap->real_end) || + (inode+num-1 > bitmap->real_end)) { ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST, inode, bitmap->description); return 0; @@ -581,7 +583,8 @@ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap, { int i; - if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { + if ((block < bitmap->start) || (block > bitmap->end) || + (block+num-1 > bitmap->end)) { ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block, bitmap->description); return; @@ -595,7 +598,8 @@ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap, { int i; - if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { + if ((block < bitmap->start) || (block > bitmap->end) || + (block+num-1 > bitmap->end)) { ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block, bitmap->description); return; diff --git a/lib/ext2fs/gen_bitmap64.c b/lib/ext2fs/gen_bitmap64.c index 3fc734981..47ba2baf9 100644 --- a/lib/ext2fs/gen_bitmap64.c +++ b/lib/ext2fs/gen_bitmap64.c @@ -637,7 +637,8 @@ int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap, bmap, block); if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((block+num-1) & ~0xffffffffULL) { + if ((block & ~0xffffffffULL) || + ((block+num-1) & ~0xffffffffULL)) { ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return EINVAL; @@ -657,7 +658,8 @@ int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap, end >>= bmap->cluster_bits; num = end - block; - if ((block < bmap->start) || (block+num-1 > bmap->end)) { + if ((block < bmap->start) || (block > bmap->end) || + (block+num-1 > bmap->end)) { ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, block, bmap->description); return EINVAL; @@ -675,7 +677,8 @@ void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap, return; if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((block+num-1) & ~0xffffffffULL) { + if ((block & ~0xffffffffULL) || + ((block+num-1) & ~0xffffffffULL)) { ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return; @@ -695,7 +698,8 @@ void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap, end >>= bmap->cluster_bits; num = end - block; - if ((block < bmap->start) || (block+num-1 > bmap->end)) { + if ((block < bmap->start) || (block > bmap->end) || + (block+num-1 > bmap->end)) { ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block, bmap->description); return; @@ -713,7 +717,8 @@ void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap, return; if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((block+num-1) & ~0xffffffffULL) { + if ((block & ~0xffffffffULL) || + ((block+num-1) & ~0xffffffffULL)) { ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return; @@ -733,7 +738,8 @@ void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap, end >>= bmap->cluster_bits; num = end - block; - if ((block < bmap->start) || (block+num-1 > bmap->end)) { + if ((block < bmap->start) || (block > bmap->end) || + (block+num-1 > bmap->end)) { ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block, bmap->description); return; -- 2.39.2