Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > 087c07ba1119dc259cb65abc62ef69e9 > files > 19

e2fsprogs-1.39-20.el5.src.rpm

# HG changeset patch
# User tytso@mit.edu
# Date Tue Sep 12 14:55:22 2006 -0400
# Node ID 90cd01f7fcd6293846f0b3ca6ce2b007e3dd7d51
# parent: cb841a8195a7aa87e8d0c95686291e8fb53358df
Fix loops over group descriptors to prevent 2**32-1 block number overflows

For loops iterating over all group descriptors, consistently define
first_block and last_block in a way that they are inclusive of the
range, and do not overflow.

Previously on the last block group we did a test of <= first +
dec_blocks; this would actually wrap back to 0 for a total block count
of 2^32-1

Also add handling of last block group which may be smaller.

Signed-off-by: Eric Sandeen <esandeen@redhat.com>

Index: e2fsprogs-1.39-my-patches-from-ted/e2fsck/ChangeLog
===================================================================
--- e2fsprogs-1.39-my-patches-from-ted.orig/e2fsck/ChangeLog
+++ e2fsprogs-1.39-my-patches-from-ted/e2fsck/ChangeLog
@@ -1,3 +1,11 @@
+2006-08-30  Eric Sandeen <esandeen@redhat.com>
+
+	* pass1b.c (check_if_fs_block): Change block group loop to use 
+		a common pattern of first_block/last_block, etc.
+	
+	* super.c (check_super_block): Avoid overflows when iterating over
+		group descriptors on very large filesystems
+
 2006-08-30  Theodore Tso  <tytso@mit.edu>
 
 	* pass5.c (check_inode_bitmaps, check_inode_end, check_block_end):
Index: e2fsprogs-1.39-my-patches-from-ted/e2fsck/pass1b.c
===================================================================
--- e2fsprogs-1.39-my-patches-from-ted.orig/e2fsck/pass1b.c
+++ e2fsprogs-1.39-my-patches-from-ted/e2fsck/pass1b.c
@@ -779,16 +779,16 @@ errout:
 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
 {
 	ext2_filsys fs = ctx->fs;
-	blk_t	block;
+	blk_t	first_block;
 	dgrp_t	i;
 	
-	block = fs->super->s_first_data_block;
+	first_block = fs->super->s_first_data_block;
 	for (i = 0; i < fs->group_desc_count; i++) {
 
-		/* Check superblocks/block group descriptros */
+		/* Check superblocks/block group descriptors */
 		if (ext2fs_bg_has_super(fs, i)) {
-			if (test_block >= block &&
-			    (test_block <= block + fs->desc_blocks))
+			if (test_block >= first_block &&
+			    (test_block <= first_block + fs->desc_blocks))
 				return 1;
 		}
 		
@@ -804,7 +804,7 @@ static int check_if_fs_block(e2fsck_t ct
 		    (test_block == fs->group_desc[i].bg_inode_bitmap))
 			return 1;
 		
-		block += fs->super->s_blocks_per_group;
+		first_block += fs->super->s_blocks_per_group;
 	}
 	return 0;
 }
Index: e2fsprogs-1.39-my-patches-from-ted/e2fsck/super.c
===================================================================
--- e2fsprogs-1.39-my-patches-from-ted.orig/e2fsck/super.c
+++ e2fsprogs-1.39-my-patches-from-ted/e2fsck/super.c
@@ -566,15 +566,17 @@ void check_super_block(e2fsck_t ctx)
 	 * Verify the group descriptors....
 	 */
 	first_block =  sb->s_first_data_block;
-	last_block = first_block + blocks_per_group;
 
 	for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
 		pctx.group = i;
 		
 		if (i == fs->group_desc_count - 1)
-			last_block = sb->s_blocks_count;
+			last_block = sb->s_blocks_count - 1;
+		else
+			last_block = first_block + blocks_per_group - 1;
+
 		if ((gd->bg_block_bitmap < first_block) ||
-		    (gd->bg_block_bitmap >= last_block)) {
+		    (gd->bg_block_bitmap > last_block)) {
 			pctx.blk = gd->bg_block_bitmap;
 			if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
 				gd->bg_block_bitmap = 0;
@@ -584,7 +586,7 @@ void check_super_block(e2fsck_t ctx)
 			ctx->invalid_bitmaps++;
 		}
 		if ((gd->bg_inode_bitmap < first_block) ||
-		    (gd->bg_inode_bitmap >= last_block)) {
+		    (gd->bg_inode_bitmap > last_block)) {
 			pctx.blk = gd->bg_inode_bitmap;
 			if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
 				gd->bg_inode_bitmap = 0;
@@ -595,7 +597,7 @@ void check_super_block(e2fsck_t ctx)
 		}
 		if ((gd->bg_inode_table < first_block) ||
 		    ((gd->bg_inode_table +
-		      fs->inode_blocks_per_group - 1) >= last_block)) {
+		      fs->inode_blocks_per_group - 1) > last_block)) {
 			pctx.blk = gd->bg_inode_table;
 			if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
 				gd->bg_inode_table = 0;
@@ -607,7 +609,6 @@ void check_super_block(e2fsck_t ctx)
 		free_blocks += gd->bg_free_blocks_count;
 		free_inodes += gd->bg_free_inodes_count;
 		first_block += sb->s_blocks_per_group;
-		last_block += sb->s_blocks_per_group;
 
 		if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
 		    (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
Index: e2fsprogs-1.39-my-patches-from-ted/lib/ext2fs/ChangeLog
===================================================================
--- e2fsprogs-1.39-my-patches-from-ted.orig/lib/ext2fs/ChangeLog
+++ e2fsprogs-1.39-my-patches-from-ted/lib/ext2fs/ChangeLog
@@ -1,3 +1,8 @@
+2006-08-30  Eric Sandeen <esandeen@redhat.com>
+
+	* check_desc.c (ext2fs_check_desc): avoid overflows when iterating
+		over group descriptors on very large filesystems.
+
 2006-08-30  Theodore Tso  <tytso@mit.edu>
 
 	* bitmaps.c (ext2fs_set_bitmap_padding): Fix potential overflow
Index: e2fsprogs-1.39-my-patches-from-ted/lib/ext2fs/check_desc.c
===================================================================
--- e2fsprogs-1.39-my-patches-from-ted.orig/lib/ext2fs/check_desc.c
+++ e2fsprogs-1.39-my-patches-from-ted/lib/ext2fs/check_desc.c
@@ -32,37 +32,41 @@
 errcode_t ext2fs_check_desc(ext2_filsys fs)
 {
 	dgrp_t i;
-	blk_t block = fs->super->s_first_data_block;
-	blk_t next;
+	blk_t first_block = fs->super->s_first_data_block;
+	blk_t last_block;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
 	for (i = 0; i < fs->group_desc_count; i++) {
-		next = block + fs->super->s_blocks_per_group;
+		if (i == fs->group_desc_count - 1)
+			last_block = fs->super->s_blocks_count - 1;
+		else
+			last_block = first_block +
+				     fs->super->s_blocks_per_group - 1;
 		/*
 		 * Check to make sure block bitmap for group is
 		 * located within the group.
 		 */
-		if (fs->group_desc[i].bg_block_bitmap < block ||
-		    fs->group_desc[i].bg_block_bitmap >= next)
+		if (fs->group_desc[i].bg_block_bitmap < first_block ||
+		    fs->group_desc[i].bg_block_bitmap > last_block)
 			return EXT2_ET_GDESC_BAD_BLOCK_MAP;
 		/*
 		 * Check to make sure inode bitmap for group is
 		 * located within the group
 		 */
-		if (fs->group_desc[i].bg_inode_bitmap < block ||
-		    fs->group_desc[i].bg_inode_bitmap >= next)
+		if (fs->group_desc[i].bg_inode_bitmap < first_block ||
+		    fs->group_desc[i].bg_inode_bitmap > last_block)
 			return EXT2_ET_GDESC_BAD_INODE_MAP;
 		/*
 		 * Check to make sure inode table for group is located
 		 * within the group
 		 */
-		if (fs->group_desc[i].bg_inode_table < block ||
+		if (fs->group_desc[i].bg_inode_table < first_block ||
 		    ((fs->group_desc[i].bg_inode_table +
-		      fs->inode_blocks_per_group) >= next))
+		      fs->inode_blocks_per_group) > last_block))
 			return EXT2_ET_GDESC_BAD_INODE_TABLE;
 		
-		block = next;
+		first_block += fs->super->s_blocks_per_group;
 	}
 	return 0;
 }
Index: e2fsprogs-1.39-my-patches-from-ted/misc/ChangeLog
===================================================================
--- e2fsprogs-1.39-my-patches-from-ted.orig/misc/ChangeLog
+++ e2fsprogs-1.39-my-patches-from-ted/misc/ChangeLog
@@ -1,3 +1,12 @@
+2006-08-30  Eric Sandeen <esandeen@redhat.com>
+
+	* dumpe2fs.c (list_desc, mark_table_blocks): Avoid overflows when
+		iterating over group descriptors on very large
+		filesystems.
+	
+	* e2image.c (mark_table_blocks): Change block group loop to use a
+		common pattern of first_block/last_block, etc.
+
 2006-08-30  Theodore Tso  <tytso@mit.edu>
 
 	* tune2fs.c (main), mke2fs.c (PRS): Use e2p_percent to properly
Index: e2fsprogs-1.39-my-patches-from-ted/misc/dumpe2fs.c
===================================================================
--- e2fsprogs-1.39-my-patches-from-ted.orig/misc/dumpe2fs.c
+++ e2fsprogs-1.39-my-patches-from-ted/misc/dumpe2fs.c
@@ -130,7 +130,7 @@ static void list_desc (ext2_filsys fs)
 {
 	unsigned long i;
 	long diff;
-	blk_t	group_blk, next_blk;
+	blk_t	first_block, last_block;
 	blk_t	super_blk, old_desc_blk, new_desc_blk;
 	char *block_bitmap=NULL, *inode_bitmap=NULL;
 	int inode_blocks_per_group, old_desc_blocks, reserved_gdt;
@@ -147,7 +147,7 @@ static void list_desc (ext2_filsys fs)
 				 EXT2_BLOCK_SIZE(fs->super);
 	reserved_gdt = fs->super->s_reserved_gdt_blocks;
 	fputc('\n', stdout);
-	group_blk = fs->super->s_first_data_block;
+	first_block = fs->super->s_first_data_block;
 	if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
 		old_desc_blocks = fs->super->s_first_meta_bg;
 	else
@@ -155,11 +155,14 @@ static void list_desc (ext2_filsys fs)
 	for (i = 0; i < fs->group_desc_count; i++) {
 		ext2fs_super_and_bgd_loc(fs, i, &super_blk, 
 					 &old_desc_blk, &new_desc_blk, 0);
-		next_blk = group_blk + fs->super->s_blocks_per_group;
-		if (next_blk > fs->super->s_blocks_count)
-			next_blk = fs->super->s_blocks_count;
+		if (i == fs->group_desc_count - 1)
+			last_block = fs->super->s_blocks_count - 1;
+		else
+			last_block = first_block +
+				     fs->super->s_blocks_per_group - 1;
+
 		printf (_("Group %lu: (Blocks "), i);
-		print_range(group_blk, next_blk - 1);
+		print_range(first_block, last_block);
 		fputs(")", stdout);
 		print_bg_opts(fs, i);
 		has_super = ((i==0) || super_blk);
@@ -188,19 +191,19 @@ static void list_desc (ext2_filsys fs)
 			fputc('\n', stdout);
 		fputs(_("  Block bitmap at "), stdout);
 		print_number(fs->group_desc[i].bg_block_bitmap);
-		diff = fs->group_desc[i].bg_block_bitmap - group_blk;
+		diff = fs->group_desc[i].bg_block_bitmap - first_block;
 		if (diff >= 0)
 			printf(" (+%ld)", diff);
 		fputs(_(", Inode bitmap at "), stdout);
 		print_number(fs->group_desc[i].bg_inode_bitmap);
-		diff = fs->group_desc[i].bg_inode_bitmap - group_blk;
+		diff = fs->group_desc[i].bg_inode_bitmap - first_block;
 		if (diff >= 0)
 			printf(" (+%ld)", diff);
 		fputs(_("\n  Inode table at "), stdout);
 		print_range(fs->group_desc[i].bg_inode_table,
 			    fs->group_desc[i].bg_inode_table +
 			    inode_blocks_per_group - 1);
-		diff = fs->group_desc[i].bg_inode_table - group_blk;
+		diff = fs->group_desc[i].bg_inode_table - first_block;
 		if (diff > 0)
 			printf(" (+%ld)", diff);
 		printf (_("\n  %d free blocks, %d free inodes, "
@@ -223,7 +226,7 @@ static void list_desc (ext2_filsys fs)
 			fputc('\n', stdout);
 			inode_bitmap += fs->super->s_inodes_per_group / 8;
 		}
-		group_blk = next_blk;
+		first_block += fs->super->s_blocks_per_group;
 	}
 }
 
Index: e2fsprogs-1.39-my-patches-from-ted/misc/e2image.c
===================================================================
--- e2fsprogs-1.39-my-patches-from-ted.orig/misc/e2image.c
+++ e2fsprogs-1.39-my-patches-from-ted/misc/e2image.c
@@ -244,21 +244,21 @@ static int process_file_block(ext2_filsy
 
 static void mark_table_blocks(ext2_filsys fs)
 {
-	blk_t	block, b;
+	blk_t	first_block, b;
 	unsigned int	i,j;
 	
-	block = fs->super->s_first_data_block;
+	first_block = fs->super->s_first_data_block;
 	/*
 	 * Mark primary superblock
 	 */
-	ext2fs_mark_block_bitmap(meta_block_map, block);
+	ext2fs_mark_block_bitmap(meta_block_map, first_block);
 			
 	/*
 	 * Mark the primary superblock descriptors
 	 */
 	for (j = 0; j < fs->desc_blocks; j++) {
 		ext2fs_mark_block_bitmap(meta_block_map,
-			 ext2fs_descriptor_block_loc(fs, block, j));
+			 ext2fs_descriptor_block_loc(fs, first_block, j));
 	}
 
 	for (i = 0; i < fs->group_desc_count; i++) {
@@ -287,7 +287,7 @@ static void mark_table_blocks(ext2_filsy
 			ext2fs_mark_block_bitmap(meta_block_map,
 				 fs->group_desc[i].bg_inode_bitmap);
 		}
-		block += fs->super->s_blocks_per_group;
+		first_block += fs->super->s_blocks_per_group;
 	}
 }