]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
Fix loops over group descriptors to prevent 2**32-1 block number overflows
authorEric Sandeen <esandeen@redhat.com>
Tue, 12 Sep 2006 18:55:22 +0000 (14:55 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 12 Sep 2006 18:55:22 +0000 (14:55 -0400)
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>
e2fsck/ChangeLog
e2fsck/pass1b.c
e2fsck/super.c
lib/ext2fs/ChangeLog
lib/ext2fs/check_desc.c
misc/ChangeLog
misc/dumpe2fs.c
misc/e2image.c

index 208b7efd7bca8cfeaa4c0de6a9784c5020af34ea..3e7b510d90d2310eafa67e136ad6f9548855ba3e 100644 (file)
@@ -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 a9640ffa2c9aee099809f4c0c381839d875c42c9..cec60cf460954319ce6dab50b5e7e640e3d9b7b1 100644 (file)
@@ -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 ctx, blk_t test_block)
                    (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 a7daa78c2f9661c5c1e1bf719ff7fe7ffd5bb324..ab11cbb713fd040a0c934ce63cf36c7129c7e106 100644 (file)
@@ -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 672a0ee4342f773bddc642568d1b230b167a5709..124b6c16655384f49374dd8a679f61d002e7e859 100644 (file)
@@ -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 2a754c7f637b9450f4b5fc1bd3af6de2094fa86b..2dd982ed0aa9597c0d9a451476fa6242fb4e1023 100644 (file)
 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 620b7f617ce7c45be2694631d445d5cef4c71f2d..a49a563637c739b360a470d730d36c93cac07157 100644 (file)
@@ -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-09-12  Theodore Tso  <tytso@mit.edu>
 
        * tune2fs.8.in, uuidgen.1: Fix minor grammar problems.  Addresses
index 821e67aa6fc2a91c2103e78ec57bca936f9bd749..2a3cf53f7d45839e85c87778fa297eedceb32bce 100644 (file)
@@ -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 4f1cfdeef04df8cedbe7c87c2c97e4d4fcf25ecd..c069b0cf83a00b0266eae497780b10c63773f802 100644 (file)
@@ -244,21 +244,21 @@ static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)),
 
 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_filsys fs)
                        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;
        }
 }