scsi: ufs: fix bugs related to null pointer access and array size
authorYaniv Gardi <ygardi@codeaurora.org>
Tue, 18 Oct 2016 00:09:24 +0000 (17:09 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 1 Dec 2018 08:48:04 +0000 (09:48 +0100)
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
drivers/scsi/ufs/ufshcd.c

index 42c459a..ce52345 100644 (file)
@@ -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];
 };
 
 /**
index 39a4e61..3ff9882 100644 (file)
@@ -796,10 +796,14 @@ static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp)
        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));
        }
 }
 
@@ -5161,7 +5165,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.
@@ -5182,7 +5189,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);
@@ -5212,10 +5222,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);