Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d08c3b78 authored by Vinit Agnihotri's avatar Vinit Agnihotri Committed by Artem Bityutskiy
Browse files

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: default avatarVinit Agnihotri <vinit.agnihotri@gmail.com>
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
parent 2f3cdb55
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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");
+6 −3
Original line number Diff line number Diff line
@@ -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]);