forked from Minki/linux
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>
This commit is contained in:
parent
2f3cdb55ee
commit
d08c3b78b8
@ -280,7 +280,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
|
||||
if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
|
||||
vol->used_ebs = vol->reserved_pebs;
|
||||
vol->last_eb_bytes = vol->usable_leb_size;
|
||||
vol->used_bytes = vol->used_ebs * vol->usable_leb_size;
|
||||
vol->used_bytes =
|
||||
(long long)vol->used_ebs * vol->usable_leb_size;
|
||||
} else {
|
||||
bytes = vol->used_bytes;
|
||||
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)
|
||||
if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
|
||||
vol->used_ebs = reserved_pebs;
|
||||
vol->last_eb_bytes = vol->usable_leb_size;
|
||||
vol->used_bytes = vol->used_ebs * vol->usable_leb_size;
|
||||
vol->used_bytes =
|
||||
(long long)vol->used_ebs * vol->usable_leb_size;
|
||||
}
|
||||
|
||||
paranoid_check_volumes(ubi);
|
||||
@ -739,7 +741,7 @@ static void paranoid_check_volume(struct ubi_device *ubi, int vol_id)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
n = vol->used_ebs * vol->usable_leb_size;
|
||||
n = (long long)vol->used_ebs * vol->usable_leb_size;
|
||||
if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
|
||||
if (vol->corrupted != 0) {
|
||||
ubi_err("corrupted dynamic volume");
|
||||
|
@ -531,7 +531,8 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
|
||||
if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
|
||||
vol->used_ebs = vol->reserved_pebs;
|
||||
vol->last_eb_bytes = vol->usable_leb_size;
|
||||
vol->used_bytes = vol->used_ebs * vol->usable_leb_size;
|
||||
vol->used_bytes =
|
||||
(long long)vol->used_ebs * vol->usable_leb_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -561,7 +562,8 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
|
||||
}
|
||||
|
||||
vol->used_ebs = sv->used_ebs;
|
||||
vol->used_bytes = (vol->used_ebs - 1) * vol->usable_leb_size;
|
||||
vol->used_bytes =
|
||||
(long long)(vol->used_ebs - 1) * vol->usable_leb_size;
|
||||
vol->used_bytes += sv->last_data_size;
|
||||
vol->last_eb_bytes = sv->last_data_size;
|
||||
}
|
||||
@ -578,7 +580,8 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
|
||||
vol->usable_leb_size = ubi->leb_size;
|
||||
vol->used_ebs = vol->reserved_pebs;
|
||||
vol->last_eb_bytes = vol->reserved_pebs;
|
||||
vol->used_bytes = vol->used_ebs * (ubi->leb_size - vol->data_pad);
|
||||
vol->used_bytes =
|
||||
(long long)vol->used_ebs * (ubi->leb_size - vol->data_pad);
|
||||
vol->vol_id = UBI_LAYOUT_VOL_ID;
|
||||
|
||||
ubi_assert(!ubi->volumes[i]);
|
||||
|
Loading…
Reference in New Issue
Block a user