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

Commit f18893ca authored by Can Guo's avatar Can Guo
Browse files

scsi: ufs: Fix unexpected values get from ufshcd_read_desc_param()



Since WB feature has been added, WB related sysfs entries can be accessed
even when an UFS device does not support WB feature. In that case, the
descriptors which are not supported by the UFS device may be wrongly
reported when they are accessed from their corrsponding sysfs entries.
Fix it by adding a sanity check of parameter offset against the actual
decriptor length.

Change-Id: I8a82abcb9ab881318634ae2f490b5276088d03f3
Signed-off-by: default avatarCan Guo <cang@codeaurora.org>
parent c3ccd954
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -4550,14 +4550,21 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,

	/* Sanity checks */
	if (ret || !buff_len) {
		dev_err(hba->dev, "%s: Failed to get full descriptor length",
		dev_err(hba->dev, "%s: Failed to get full descriptor length\n",
			__func__);
		return ret;
	}

	if (param_offset >= buff_len ||
	    param_offset + param_size > buff_len) {
		dev_err(hba->dev, "%s: Invalid offset 0x%x or size 0x%x in descriptor IDN 0x%x, length 0x%x\n",
			__func__, param_offset, param_size, desc_id, buff_len);
		return -EINVAL;
	}

	/* Check whether we need temp memory */
	if (param_offset != 0 || param_size < buff_len) {
		desc_buf = kmalloc(buff_len, GFP_KERNEL);
	if (param_offset != 0) {
		desc_buf = kzalloc(buff_len, GFP_KERNEL);
		if (!desc_buf)
			return -ENOMEM;
	} else {
@@ -4571,14 +4578,14 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
					desc_buf, &buff_len);

	if (ret) {
		dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d",
		dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d\n",
			__func__, desc_id, desc_index, param_offset, ret);
		goto out;
	}

	/* Sanity check */
	if (desc_buf[QUERY_DESC_DESC_TYPE_OFFSET] != desc_id) {
		dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header",
		dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header\n",
			__func__, desc_buf[QUERY_DESC_DESC_TYPE_OFFSET]);
		ret = -EINVAL;
		goto out;