diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 627d19186d5a1..42471a08156da 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -366,7 +366,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, struct log_c *lc; uint32_t region_size; - unsigned int region_count; + sector_t region_count; size_t bitset_size, buf_size; int r; char dummy; @@ -395,6 +395,10 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, } region_count = dm_sector_div_up(ti->len, region_size); + if (region_count > UINT_MAX) { + DMWARN("region count exceeds limit of %u", UINT_MAX); + return -EINVAL; + } lc = kmalloc(sizeof(*lc), GFP_KERNEL); if (!lc) { @@ -416,6 +420,9 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, bitset_size = dm_round_up(region_count, sizeof(*lc->clean_bits) << BYTE_SHIFT); bitset_size >>= BYTE_SHIFT; + /* Handle dm_round_up rollover on 32-bit systems */ + if (!bitset_size) + bitset_size = 1UL << (BITS_PER_LONG - BYTE_SHIFT); lc->bitset_uint32_count = bitset_size / sizeof(*lc->clean_bits);