Unverified Commit 01b14aed authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!4036 ubi: fix slab-out-of-bounds in ubi_eba_get_ldesc+0xfb/0x130

parents 806899e4 dad36c41
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1459,7 +1459,14 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
	}

	ubi_assert(vol->eba_tbl->entries[lnum].pnum == from);

	/**
	 * The volumes_lock lock is needed here to prevent the expired old eba_tbl
	 * being updated when the eba_tbl is copied in the ubi_resize_volume() process.
	 */
	spin_lock(&ubi->volumes_lock);
	vol->eba_tbl->entries[lnum].pnum = to;
	spin_unlock(&ubi->volumes_lock);

out_unlock_buf:
	mutex_unlock(&ubi->buf_mutex);
+17 −7
Original line number Diff line number Diff line
@@ -408,6 +408,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
	struct ubi_device *ubi = vol->ubi;
	struct ubi_vtbl_record vtbl_rec;
	struct ubi_eba_table *new_eba_tbl = NULL;
	struct ubi_eba_table *old_eba_tbl = NULL;
	int vol_id = vol->vol_id;

	if (ubi->ro_mode)
@@ -453,10 +454,13 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
			err = -ENOSPC;
			goto out_free;
		}

		ubi->avail_pebs -= pebs;
		ubi->rsvd_pebs += pebs;
		ubi_eba_copy_table(vol, new_eba_tbl, vol->reserved_pebs);
		ubi_eba_replace_table(vol, new_eba_tbl);
		old_eba_tbl = vol->eba_tbl;
		vol->eba_tbl = new_eba_tbl;
		vol->reserved_pebs = reserved_pebs;
		spin_unlock(&ubi->volumes_lock);
	}

@@ -471,7 +475,9 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
		ubi->avail_pebs -= pebs;
		ubi_update_reserved(ubi);
		ubi_eba_copy_table(vol, new_eba_tbl, reserved_pebs);
		ubi_eba_replace_table(vol, new_eba_tbl);
		old_eba_tbl = vol->eba_tbl;
		vol->eba_tbl = new_eba_tbl;
		vol->reserved_pebs = reserved_pebs;
		spin_unlock(&ubi->volumes_lock);
	}

@@ -493,7 +499,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
	if (err)
		goto out_acc;

	vol->reserved_pebs = reserved_pebs;
	if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
		vol->used_ebs = reserved_pebs;
		vol->last_eb_bytes = vol->usable_leb_size;
@@ -501,19 +506,24 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
			(long long)vol->used_ebs * vol->usable_leb_size;
	}

	/* destroy old table */
	ubi_eba_destroy_table(old_eba_tbl);
	ubi_volume_notify(ubi, vol, UBI_VOLUME_RESIZED);
	self_check_volumes(ubi);
	return err;

out_acc:
	if (pebs > 0) {
	spin_lock(&ubi->volumes_lock);
	vol->reserved_pebs = reserved_pebs - pebs;
	if (pebs > 0) {
		ubi->rsvd_pebs -= pebs;
		ubi->avail_pebs += pebs;
		spin_unlock(&ubi->volumes_lock);
		ubi_eba_copy_table(vol, old_eba_tbl, vol->reserved_pebs);
	} else {
		ubi_eba_copy_table(vol, old_eba_tbl, reserved_pebs);
	}
	return err;

	vol->eba_tbl = old_eba_tbl;
	spin_unlock(&ubi->volumes_lock);
out_free:
	ubi_eba_destroy_table(new_eba_tbl);
	return err;