From dd4f565d5ac3b1f37100291fb1cd067dd0d55d05 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 14 Jan 2013 19:29:54 -0500 Subject: [PATCH] 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" Reviewed-by: Zheng Liu --- lib/ext2fs/initialize.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c index b0c15d2..5afdc27 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)) -- 1.8.3.1