Skip to content

Commit cd69732

Browse files
Jaegeuk Kimgregkh
authored andcommitted
scsi: ufs: WB is only available on LUN #0 to #7
[ Upstream commit a2fca52 ] Kernel stack violation when getting unit_descriptor/wb_buf_alloc_units from rpmb LUN. The reason is that the unit descriptor length is different per LU. The length of Normal LU is 45 while the one of rpmb LU is 35. int ufshcd_read_desc_param(struct ufs_hba *hba, ...) { param_offset=41; param_size=4; buff_len=45; ... buff_len=35 by rpmb LU; 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; --> param_size = 250; memcpy(param_read_buf, &desc_buf[param_offset], param_size); --> memcpy(param_read_buf, desc_buf+41, 250); [ 141.868974][ T9174] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: wb_buf_alloc_units_show+0x11c/0x11c } } Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Avri Altman <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 2b61057 commit cd69732

File tree

3 files changed

+7
-4
lines changed

3 files changed

+7
-4
lines changed

drivers/scsi/ufs/ufs-sysfs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,8 @@ static ssize_t _pname##_show(struct device *dev, \
785785
struct scsi_device *sdev = to_scsi_device(dev); \
786786
struct ufs_hba *hba = shost_priv(sdev->host); \
787787
u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun); \
788-
if (!ufs_is_valid_unit_desc_lun(&hba->dev_info, lun)) \
788+
if (!ufs_is_valid_unit_desc_lun(&hba->dev_info, lun, \
789+
_duname##_DESC_PARAM##_puname)) \
789790
return -EINVAL; \
790791
return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_##_duname, \
791792
lun, _duname##_DESC_PARAM##_puname, buf, _size); \

drivers/scsi/ufs/ufs.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,13 +551,15 @@ struct ufs_dev_info {
551551
* @return: true if the lun has a matching unit descriptor, false otherwise
552552
*/
553553
static inline bool ufs_is_valid_unit_desc_lun(struct ufs_dev_info *dev_info,
554-
u8 lun)
554+
u8 lun, u8 param_offset)
555555
{
556556
if (!dev_info || !dev_info->max_lu_supported) {
557557
pr_err("Max General LU supported by UFS isn't initialized\n");
558558
return false;
559559
}
560-
560+
/* WB is available only for the logical unit from 0 to 7 */
561+
if (param_offset == UNIT_DESC_PARAM_WB_BUF_ALLOC_UNITS)
562+
return lun < UFS_UPIU_MAX_WB_LUN_ID;
561563
return lun == UFS_UPIU_RPMB_WLUN || (lun < dev_info->max_lu_supported);
562564
}
563565

drivers/scsi/ufs/ufshcd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3378,7 +3378,7 @@ static inline int ufshcd_read_unit_desc_param(struct ufs_hba *hba,
33783378
* Unit descriptors are only available for general purpose LUs (LUN id
33793379
* from 0 to 7) and RPMB Well known LU.
33803380
*/
3381-
if (!ufs_is_valid_unit_desc_lun(&hba->dev_info, lun))
3381+
if (!ufs_is_valid_unit_desc_lun(&hba->dev_info, lun, param_offset))
33823382
return -EOPNOTSUPP;
33833383

33843384
return ufshcd_read_desc_param(hba, QUERY_DESC_IDN_UNIT, lun,

0 commit comments

Comments
 (0)