Commit 1699f980 authored by Can Guo's avatar Can Guo Committed by Martin K. Petersen

scsi: ufs: Fix unexpected values from ufshcd_read_desc_param()

WB-related sysfs entries can be accessed even when an UFS device does not
support the feature. 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.

Link: https://lore.kernel.org/r/1603346348-14149-1-git-send-email-cang@codeaurora.orgReviewed-by: default avatarAsutosh Das <asutoshd@codeaurora.org>
Acked-by: default avatarDaejun Park <daejun7.park@samsung.com>
Signed-off-by: default avatarCan Guo <cang@codeaurora.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent f3619935
......@@ -3192,13 +3192,19 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
/* Get the length of descriptor */
ufshcd_map_desc_id_to_length(hba, desc_id, &buff_len);
if (!buff_len) {
dev_err(hba->dev, "%s: Failed to get desc length", __func__);
dev_err(hba->dev, "%s: Failed to get desc length\n", __func__);
return -EINVAL;
}
if (param_offset >= buff_len) {
dev_err(hba->dev, "%s: Invalid offset 0x%x in descriptor IDN 0x%x, length 0x%x\n",
__func__, param_offset, 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);
desc_buf = kzalloc(buff_len, GFP_KERNEL);
if (!desc_buf)
return -ENOMEM;
} else {
......@@ -3212,14 +3218,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;
......@@ -3229,12 +3235,12 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
buff_len = desc_buf[QUERY_DESC_LENGTH_OFFSET];
ufshcd_update_desc_length(hba, desc_id, desc_index, buff_len);
/* Check wherher we will not copy more data, than available */
if (is_kmalloc && (param_offset + param_size) > buff_len)
param_size = buff_len - param_offset;
if (is_kmalloc)
if (is_kmalloc) {
/* Make sure we don't copy more data than available */
if (param_offset + param_size > buff_len)
param_size = buff_len - param_offset;
memcpy(param_read_buf, &desc_buf[param_offset], param_size);
}
out:
if (is_kmalloc)
kfree(desc_buf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment