aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2013-01-14 19:29:54 -0500
committerTheodore Ts'o <tytso@mit.edu>2013-01-15 14:08:18 -0500
commitdd4f565d5ac3b1f37100291fb1cd067dd0d55d05 (patch)
treedb6eef9d4716cb26c7fbf324de396c0d3a6afd6c
parent86a985e74987b08090ecbacf3d02c8d80594c809 (diff)
downloade2fsprogs-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.c15
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))