mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
dm clone: Add overflow check for number of regions
commitcd481c1226upstream. Add overflow check for clone->nr_regions variable, which holds the number of regions of the target. The overflow can occur with sufficiently large devices, if BITS_PER_LONG == 32. E.g., if the region size is 8 sectors (4K), the overflow would occur for device sizes > 34359738360 sectors (~16TB). This could result in multiple device sectors wrongly mapping to the same region number, due to the truncation from 64 bits to 32 bits, which would lead to data corruption. Fixes:7431b7835f("dm: add clone target") Cc: stable@vger.kernel.org # v5.4+ Signed-off-by: Nikos Tsironis <ntsironis@arrikto.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
2e70305934
commit
996f8f1ba7
@@ -1775,6 +1775,7 @@ error:
|
||||
static int clone_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||
{
|
||||
int r;
|
||||
sector_t nr_regions;
|
||||
struct clone *clone;
|
||||
struct dm_arg_set as;
|
||||
|
||||
@@ -1816,7 +1817,16 @@ static int clone_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||
goto out_with_source_dev;
|
||||
|
||||
clone->region_shift = __ffs(clone->region_size);
|
||||
clone->nr_regions = dm_sector_div_up(ti->len, clone->region_size);
|
||||
nr_regions = dm_sector_div_up(ti->len, clone->region_size);
|
||||
|
||||
/* Check for overflow */
|
||||
if (nr_regions != (unsigned long)nr_regions) {
|
||||
ti->error = "Too many regions. Consider increasing the region size";
|
||||
r = -EOVERFLOW;
|
||||
goto out_with_source_dev;
|
||||
}
|
||||
|
||||
clone->nr_regions = nr_regions;
|
||||
|
||||
r = validate_nr_regions(clone->nr_regions, &ti->error);
|
||||
if (r)
|
||||
|
||||
Reference in New Issue
Block a user