Skip to content

Commit 1699f98

Browse files
Can Guomartinkpetersen
authored andcommitted
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/[email protected] Reviewed-by: Asutosh Das <[email protected]> Acked-by: Daejun Park <[email protected]> Signed-off-by: Can Guo <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent f361993 commit 1699f98

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

drivers/scsi/ufs/ufshcd.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3192,13 +3192,19 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
31923192
/* Get the length of descriptor */
31933193
ufshcd_map_desc_id_to_length(hba, desc_id, &buff_len);
31943194
if (!buff_len) {
3195-
dev_err(hba->dev, "%s: Failed to get desc length", __func__);
3195+
dev_err(hba->dev, "%s: Failed to get desc length\n", __func__);
3196+
return -EINVAL;
3197+
}
3198+
3199+
if (param_offset >= buff_len) {
3200+
dev_err(hba->dev, "%s: Invalid offset 0x%x in descriptor IDN 0x%x, length 0x%x\n",
3201+
__func__, param_offset, desc_id, buff_len);
31963202
return -EINVAL;
31973203
}
31983204

31993205
/* Check whether we need temp memory */
32003206
if (param_offset != 0 || param_size < buff_len) {
3201-
desc_buf = kmalloc(buff_len, GFP_KERNEL);
3207+
desc_buf = kzalloc(buff_len, GFP_KERNEL);
32023208
if (!desc_buf)
32033209
return -ENOMEM;
32043210
} else {
@@ -3212,14 +3218,14 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
32123218
desc_buf, &buff_len);
32133219

32143220
if (ret) {
3215-
dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d",
3221+
dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d\n",
32163222
__func__, desc_id, desc_index, param_offset, ret);
32173223
goto out;
32183224
}
32193225

32203226
/* Sanity check */
32213227
if (desc_buf[QUERY_DESC_DESC_TYPE_OFFSET] != desc_id) {
3222-
dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header",
3228+
dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header\n",
32233229
__func__, desc_buf[QUERY_DESC_DESC_TYPE_OFFSET]);
32243230
ret = -EINVAL;
32253231
goto out;
@@ -3229,12 +3235,12 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
32293235
buff_len = desc_buf[QUERY_DESC_LENGTH_OFFSET];
32303236
ufshcd_update_desc_length(hba, desc_id, desc_index, buff_len);
32313237

3232-
/* Check wherher we will not copy more data, than available */
3233-
if (is_kmalloc && (param_offset + param_size) > buff_len)
3234-
param_size = buff_len - param_offset;
3235-
3236-
if (is_kmalloc)
3238+
if (is_kmalloc) {
3239+
/* Make sure we don't copy more data than available */
3240+
if (param_offset + param_size > buff_len)
3241+
param_size = buff_len - param_offset;
32373242
memcpy(param_read_buf, &desc_buf[param_offset], param_size);
3243+
}
32383244
out:
32393245
if (is_kmalloc)
32403246
kfree(desc_buf);

0 commit comments

Comments
 (0)