From: Theodore Ts'o Date: Wed, 30 Jan 2019 04:07:27 +0000 (-0500) Subject: libext2fs: add checks for block number wrapping for bitmap range functions X-Git-Tag: v1.44.6~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=92c5594969caad29ffd333441ac85bdaa4b7ac3e;p=thirdparty%2Fe2fsprogs.git 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 --- 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;