diff options
author | Vinit Agnihotri <vinit.agnihotri@gmail.com> | 2007-07-10 06:04:59 -0400 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-07-18 09:58:12 -0400 |
commit | d08c3b78b8c46a01b8fa59037a0d9fbb777fb465 (patch) | |
tree | c27d7d436864175107fe8e2b1de3a11b928c975a /drivers/mtd/ubi/vmt.c | |
parent | 2f3cdb55eef4fa1398965e893f731fb6e6312d34 (diff) |
UBI: fix overflow bug
I was experiencing overflows in multiplications for
volume->used_bytes in vmt.c & vtbl.c, while creating & resizing large volumes.
vol->used_bytes is long long however its 2 operands vol->used_ebs &
vol->usable_leb_size
are int. So their multiplication for larger values causes integer overflows.
Typecasting them solves the problem.
My machine & flash details:
64Bit dual-core AMD opteron, 1 GB RAM, linux 2.6.18.3.
mtd size = 6GB, volume size= 5GB, peb_size = 4MB.
heres patch which does the fix.
Signed-off-by: Vinit Agnihotri <vinit.agnihotri@gmail.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi/vmt.c')
-rw-r--r-- | drivers/mtd/ubi/vmt.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index d62dac90e108..ea0d5c825ab4 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c | |||
@@ -280,7 +280,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | |||
280 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { | 280 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { |
281 | vol->used_ebs = vol->reserved_pebs; | 281 | vol->used_ebs = vol->reserved_pebs; |
282 | vol->last_eb_bytes = vol->usable_leb_size; | 282 | vol->last_eb_bytes = vol->usable_leb_size; |
283 | vol->used_bytes = vol->used_ebs * vol->usable_leb_size; | 283 | vol->used_bytes = |
284 | (long long)vol->used_ebs * vol->usable_leb_size; | ||
284 | } else { | 285 | } else { |
285 | bytes = vol->used_bytes; | 286 | bytes = vol->used_bytes; |
286 | vol->last_eb_bytes = do_div(bytes, vol->usable_leb_size); | 287 | vol->last_eb_bytes = do_div(bytes, vol->usable_leb_size); |
@@ -538,7 +539,8 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) | |||
538 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { | 539 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { |
539 | vol->used_ebs = reserved_pebs; | 540 | vol->used_ebs = reserved_pebs; |
540 | vol->last_eb_bytes = vol->usable_leb_size; | 541 | vol->last_eb_bytes = vol->usable_leb_size; |
541 | vol->used_bytes = vol->used_ebs * vol->usable_leb_size; | 542 | vol->used_bytes = |
543 | (long long)vol->used_ebs * vol->usable_leb_size; | ||
542 | } | 544 | } |
543 | 545 | ||
544 | paranoid_check_volumes(ubi); | 546 | paranoid_check_volumes(ubi); |
@@ -739,7 +741,7 @@ static void paranoid_check_volume(struct ubi_device *ubi, int vol_id) | |||
739 | goto fail; | 741 | goto fail; |
740 | } | 742 | } |
741 | 743 | ||
742 | n = vol->used_ebs * vol->usable_leb_size; | 744 | n = (long long)vol->used_ebs * vol->usable_leb_size; |
743 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { | 745 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { |
744 | if (vol->corrupted != 0) { | 746 | if (vol->corrupted != 0) { |
745 | ubi_err("corrupted dynamic volume"); | 747 | ubi_err("corrupted dynamic volume"); |