Whamcloud - gitweb
Detect overflows in loop counters
authorEric Sandeen <esandeen@redhat.com>
Wed, 30 Aug 2006 06:16:55 +0000 (02:16 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 30 Aug 2006 06:16:55 +0000 (02:16 -0400)
For loops such as:

for (i=1; i <= fs->super->s_blocks_count; i++) {
        <do_stuff>
}

if i is an int and s_blocks_count is (2^32-1), the condition is never false.
Change these loops to:

for (i=1; i <= fs->super->s_blocks_count && i > 0; i++) {
        <do_stuff>
}

to stop the loop when we overflow i

Signed-off-by: Eric Sandeen <esandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
e2fsck/ChangeLog
e2fsck/pass4.c
e2fsck/pass5.c
lib/ext2fs/ChangeLog
lib/ext2fs/bitmaps.c
resize/ChangeLog
resize/resize2fs.c

index a14563c..208b7ef 100644 (file)
@@ -1,3 +1,9 @@
+2006-08-30  Theodore Tso  <tytso@mit.edu>
+
+       * pass5.c (check_inode_bitmaps, check_inode_end, check_block_end):
+       * pass4.c (e2fsck_pass4): Fix potential overflow problems when the
+               number of blocks is close to 2**31.
+
 2006-08-29  Theodore Tso  <tytso@mit.edu>
 
        * super.c (release_inode_blocks): Fix silly spelling error.
index 985e8f6..0f92da0 100644 (file)
@@ -110,8 +110,9 @@ void e2fsck_pass4(e2fsck_t ctx)
        if (ctx->progress)
                if ((ctx->progress)(ctx, 4, 0, maxgroup))
                        return;
-       
-       for (i=1; i <= fs->super->s_inodes_count; i++) {
+
+       /* Protect loop from wrap-around if s_inodes_count maxed */
+       for (i=1; i <= fs->super->s_inodes_count && i > 0; i++) {
                if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
                        return;
                if ((i % fs->super->s_inodes_per_group) == 0) {
index eb3ebf0..7467854 100644 (file)
@@ -370,7 +370,8 @@ redo_counts:
                        EXT2_BG_INODE_UNINIT))
                skip_group++;
 
-       for (i = 1; i <= fs->super->s_inodes_count; i++) {
+       /* Protect loop from wrap-around if inodes_count is maxed */
+       for (i = 1; i <= fs->super->s_inodes_count && i > 0; i++) {
                actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
                if (skip_group) 
                        bitmap = 0;
@@ -528,8 +529,9 @@ static void check_inode_end(e2fsck_t ctx)
        }
        if (save_inodes_count == end)
                return;
-       
-       for (i = save_inodes_count + 1; i <= end; i++) {
+
+       /* protect loop from wrap-around if end is maxed */     
+       for (i = save_inodes_count + 1; i <= end && i > save_inodes_count; i++) {
                if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
                        if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
                                for (i = save_inodes_count + 1; i <= end; i++)
@@ -572,8 +574,9 @@ static void check_block_end(e2fsck_t ctx)
        }
        if (save_blocks_count == end)
                return;
-       
-       for (i = save_blocks_count + 1; i <= end; i++) {
+
+       /* Protect loop from wrap-around if end is maxed */     
+       for (i = save_blocks_count + 1; i <= end && i > save_blocks_count; i++) {
                if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
                        if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
                                for (i = save_blocks_count + 1; i <= end; i++)
index 6a2c8bd..672a0ee 100644 (file)
@@ -1,5 +1,8 @@
 2006-08-30  Theodore Tso  <tytso@mit.edu>
 
+       * bitmaps.c (ext2fs_set_bitmap_padding): Fix potential overflow
+               problems when the number of blocks is close to 2**31.
+
        * ext2fs.h (ext2fs_div_ceil): Add new function which safely
                calculates an integer division where the result is always
                rounded up while avoiding overflow errors.
index 7edd28d..696baad 100644 (file)
@@ -102,7 +102,10 @@ void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map)
 {
        __u32   i, j;
 
-       for (i=map->end+1, j = i - map->start; i <= map->real_end; i++, j++)
+       /* Protect loop from wrap-around if map->real_end is maxed */
+       for (i=map->end+1, j = i - map->start; 
+            i <= map->real_end && i > map->end; 
+            i++, j++)
                ext2fs_set_bit(j, map->bitmap);
 
        return;
index 32f116b..dea9ba6 100644 (file)
@@ -1,5 +1,9 @@
 2006-08-30  Theodore Tso  <tytso@mit.edu>
 
+       * resize2fs.c (ext2fs_calculate_summary_stats): Fix potential
+               overflow problems when the number of blocks is close to
+               2**31.
+
        * resize2fs.c (adjust_fs_info): Use ext2fs_div_ceil() instead of a
                using an open-coded expression which was subject to
                overflows.
index f6c3ede..74b517b 100644 (file)
@@ -1582,7 +1582,9 @@ static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs)
        total_free = 0;
        count = 0;
        group = 0;
-       for (ino = 1; ino <= fs->super->s_inodes_count; ino++) {
+
+       /* Protect loop from wrap-around if s_inodes_count maxed */
+       for (ino = 1; ino <= fs->super->s_inodes_count && ino > 0; ino++) {
                if (!ext2fs_fast_test_inode_bitmap(fs->inode_map, ino)) {
                        group_free++;
                        total_free++;