summaryrefslogtreecommitdiff
path: root/ext2ed
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2006-08-30 01:57:00 -0400
committerTheodore Ts'o <tytso@mit.edu>2006-08-30 01:57:00 -0400
commit69022e029f3273b3b860bf701219cd3fe615f76b (patch)
tree81ecd1b770fe3a4d8e0c325ce78bc6f0c17c927b /ext2ed
parenta3e025c7493b58ec88b775f26a41e4205a6a2c9f (diff)
Fix potential 2**32-1 overflow problems by ext2fs_div_ceil()
Add a new function, ext2fs_div_ceil(), which correctly calculates a division of two unsigned integer where the result is always rounded up the next largest integer. This is used everywhere where we might have previously caused an overflow when the number of blocks or inodes is too close to 2**32-1. Based on patches from Eric Sandeen, but generalized to use this new function Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Signed-off-by: Eric Sandeen <esandeen@redhat.com>
Diffstat (limited to 'ext2ed')
-rw-r--r--ext2ed/ChangeLog5
-rw-r--r--ext2ed/init.c11
2 files changed, 14 insertions, 2 deletions
diff --git a/ext2ed/ChangeLog b/ext2ed/ChangeLog
index fa59c241..27564906 100644
--- a/ext2ed/ChangeLog
+++ b/ext2ed/ChangeLog
@@ -1,3 +1,8 @@
+2006-08-30 Theodore Tso <tytso@mit.edu>
+
+ * init.c (div_ceil, set_file_system_info): Fix potential overflow
+ for really big filesystems.
+
2006-06-30 Theodore Ts'o <tytso@mit.edu>
* Release of E2fsprogs 1.38
diff --git a/ext2ed/init.c b/ext2ed/init.c
index f89d8934..7ab2e28c 100644
--- a/ext2ed/init.c
+++ b/ext2ed/init.c
@@ -370,6 +370,13 @@ void add_user_command (struct struct_commands *ptr,char *name,char *description,
ptr->callback [num]=callback;
}
+static unsigned int div_ceil(unsigned int a, unsigned int b)
+{
+ if (!a)
+ return 0;
+ return ((a - 1) / b) + 1;
+}
+
int set_file_system_info (void)
{
@@ -415,8 +422,8 @@ int set_file_system_info (void)
file_system_info.first_group_desc_offset=2*EXT2_MIN_BLOCK_SIZE;
else
file_system_info.first_group_desc_offset=file_system_info.block_size;
- file_system_info.groups_count=( sb->s_blocks_count-sb->s_first_data_block+sb->s_blocks_per_group-1) /
- sb->s_blocks_per_group;
+ file_system_info.groups_count = div_ceil(sb->s_blocks_count,
+ sb->s_blocks_per_group);
file_system_info.inodes_per_block=file_system_info.block_size/sizeof (struct ext2_inode);
file_system_info.blocks_per_group=sb->s_inodes_per_group/file_system_info.inodes_per_block;