| From e3ce73d69aff44421d7899b235fec5ac2c306ff4 Mon Sep 17 00:00:00 2001 |
| From: Yaniv Gardi <ygardi@codeaurora.org> |
| Date: Mon, 17 Oct 2016 17:09:24 -0700 |
| Subject: scsi: ufs: fix bugs related to null pointer access and array size |
| |
| From: Yaniv Gardi <ygardi@codeaurora.org> |
| |
| commit e3ce73d69aff44421d7899b235fec5ac2c306ff4 upstream. |
| |
| In this change there are a few fixes of possible NULL pointer access and |
| possible access to index that exceeds array boundaries. |
| |
| Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org> |
| Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Amit Pundir <amit.pundir@linaro.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/scsi/ufs/ufs.h | 3 ++- |
| drivers/scsi/ufs/ufshcd.c | 25 +++++++++++++++++++------ |
| 2 files changed, 21 insertions(+), 7 deletions(-) |
| |
| --- a/drivers/scsi/ufs/ufs.h |
| +++ b/drivers/scsi/ufs/ufs.h |
| @@ -45,6 +45,7 @@ |
| #define QUERY_DESC_MIN_SIZE 2 |
| #define QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - \ |
| (sizeof(struct utp_upiu_header))) |
| +#define RESPONSE_UPIU_SENSE_DATA_LENGTH 18 |
| |
| #define UPIU_HEADER_DWORD(byte3, byte2, byte1, byte0)\ |
| cpu_to_be32((byte3 << 24) | (byte2 << 16) |\ |
| @@ -383,7 +384,7 @@ struct utp_cmd_rsp { |
| __be32 residual_transfer_count; |
| __be32 reserved[4]; |
| __be16 sense_data_len; |
| - u8 sense_data[18]; |
| + u8 sense_data[RESPONSE_UPIU_SENSE_DATA_LENGTH]; |
| }; |
| |
| /** |
| --- a/drivers/scsi/ufs/ufshcd.c |
| +++ b/drivers/scsi/ufs/ufshcd.c |
| @@ -813,10 +813,14 @@ static inline void ufshcd_copy_sense_dat |
| int len; |
| if (lrbp->sense_buffer && |
| ufshcd_get_rsp_upiu_data_seg_len(lrbp->ucd_rsp_ptr)) { |
| + int len_to_copy; |
| + |
| len = be16_to_cpu(lrbp->ucd_rsp_ptr->sr.sense_data_len); |
| + len_to_copy = min_t(int, RESPONSE_UPIU_SENSE_DATA_LENGTH, len); |
| + |
| memcpy(lrbp->sense_buffer, |
| lrbp->ucd_rsp_ptr->sr.sense_data, |
| - min_t(int, len, SCSI_SENSE_BUFFERSIZE)); |
| + min_t(int, len_to_copy, SCSI_SENSE_BUFFERSIZE)); |
| } |
| } |
| |
| @@ -5251,7 +5255,10 @@ EXPORT_SYMBOL(ufshcd_system_suspend); |
| |
| int ufshcd_system_resume(struct ufs_hba *hba) |
| { |
| - if (!hba || !hba->is_powered || pm_runtime_suspended(hba->dev)) |
| + if (!hba) |
| + return -EINVAL; |
| + |
| + if (!hba->is_powered || pm_runtime_suspended(hba->dev)) |
| /* |
| * Let the runtime resume take care of resuming |
| * if runtime suspended. |
| @@ -5272,7 +5279,10 @@ EXPORT_SYMBOL(ufshcd_system_resume); |
| */ |
| int ufshcd_runtime_suspend(struct ufs_hba *hba) |
| { |
| - if (!hba || !hba->is_powered) |
| + if (!hba) |
| + return -EINVAL; |
| + |
| + if (!hba->is_powered) |
| return 0; |
| |
| return ufshcd_suspend(hba, UFS_RUNTIME_PM); |
| @@ -5302,10 +5312,13 @@ EXPORT_SYMBOL(ufshcd_runtime_suspend); |
| */ |
| int ufshcd_runtime_resume(struct ufs_hba *hba) |
| { |
| - if (!hba || !hba->is_powered) |
| + if (!hba) |
| + return -EINVAL; |
| + |
| + if (!hba->is_powered) |
| return 0; |
| - else |
| - return ufshcd_resume(hba, UFS_RUNTIME_PM); |
| + |
| + return ufshcd_resume(hba, UFS_RUNTIME_PM); |
| } |
| EXPORT_SYMBOL(ufshcd_runtime_resume); |
| |