scsi: hisi_sas: Avoid accessing to SSP task for SMP I/Os
authorXiang Chen <chenxiang66@hisilicon.com>
Tue, 1 Sep 2020 11:13:03 +0000 (19:13 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 3 Sep 2020 02:49:07 +0000 (22:49 -0400)
hisi_sas_slot_task_free() attempts to dereference SSP task for non-ATA
tasks. If the task is SMP, the code may reference the wrong structure
although this may not cause any problems.

To avoid this, only access to SSP task when slot->n_elem_dif is not 0 which
indicates this is an SSP task.

Link: https://lore.kernel.org/r/1598958790-232272-2-git-send-email-john.garry@huawei.com
Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hisi_sas/hisi_sas_main.c

index 11caa4b0d79773e80f17e38f4653aeeb03b3ac81..fdf5f0f1b60bc452afe264807a5d966b9a0089be 100644 (file)
@@ -229,17 +229,18 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
                task->lldd_task = NULL;
 
                if (!sas_protocol_ata(task->task_proto)) {
-                       struct sas_ssp_task *ssp_task = &task->ssp_task;
-                       struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
-
                        if (slot->n_elem)
                                dma_unmap_sg(dev, task->scatter,
                                             task->num_scatter,
                                             task->data_dir);
-                       if (slot->n_elem_dif)
+                       if (slot->n_elem_dif) {
+                               struct sas_ssp_task *ssp_task = &task->ssp_task;
+                               struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
+
                                dma_unmap_sg(dev, scsi_prot_sglist(scsi_cmnd),
                                             scsi_prot_sg_count(scsi_cmnd),
                                             task->data_dir);
+                       }
                }
        }