diff options
author | Theodore Ts'o <tytso@mit.edu> | 2013-01-14 19:29:54 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-01-15 14:08:18 -0500 |
commit | dd4f565d5ac3b1f37100291fb1cd067dd0d55d05 (patch) | |
tree | db6eef9d4716cb26c7fbf324de396c0d3a6afd6c | |
parent | 86a985e74987b08090ecbacf3d02c8d80594c809 (diff) | |
download | e2fsprogs-dd4f565d5ac3b1f37100291fb1cd067dd0d55d05.tar.gz e2fsprogs-dd4f565d5ac3b1f37100291fb1cd067dd0d55d05.tar.xz e2fsprogs-dd4f565d5ac3b1f37100291fb1cd067dd0d55d05.zip |
libext2fs: avoid 32-bit overflow in ext2fs_initialize with a 512M cluster size
If the user attemps to create a 512MB cluster, we need to adjust the
defaults to avoid a 32-bit overflow of s_blocks_per_group. Also check
to make sure that the caller of ext2fs_initialize() has not given a
value of s_clusters_per_group that would result in an overflow of
s_blocks_per_group.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
-rw-r--r-- | lib/ext2fs/initialize.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c index b0c15d2d..5afdc272 100644 --- a/lib/ext2fs/initialize.c +++ b/lib/ext2fs/initialize.c @@ -207,6 +207,8 @@ errcode_t ext2fs_initialize(const char *name, int flags, super->s_log_block_size; if (bigalloc_flag) { + unsigned long long bpg; + if (param->s_blocks_per_group && param->s_clusters_per_group && ((param->s_clusters_per_group * EXT2FS_CLUSTER_RATIO(fs)) != @@ -220,12 +222,19 @@ errcode_t ext2fs_initialize(const char *name, int flags, super->s_clusters_per_group = param->s_blocks_per_group / EXT2FS_CLUSTER_RATIO(fs); - else + else if (super->s_log_cluster_size + 15 < 32) super->s_clusters_per_group = fs->blocksize * 8; + else + super->s_clusters_per_group = (fs->blocksize - 1) * 8; if (super->s_clusters_per_group > EXT2_MAX_CLUSTERS_PER_GROUP(super)) super->s_clusters_per_group = EXT2_MAX_CLUSTERS_PER_GROUP(super); - super->s_blocks_per_group = EXT2FS_C2B(fs, - super->s_clusters_per_group); + bpg = EXT2FS_C2B(fs, + (unsigned long long) super->s_clusters_per_group); + if (bpg >= (((unsigned long long) 1) << 32)) { + retval = EXT2_ET_INVALID_ARGUMENT; + goto cleanup; + } + super->s_blocks_per_group = bpg; } else { set_field(s_blocks_per_group, fs->blocksize * 8); if (super->s_blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(super)) |