scsi: lpfc: Fix illegal memory access on Abort IOCBs
authorJames Smart <jsmart2021@gmail.com>
Wed, 21 Apr 2021 23:44:33 +0000 (16:44 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 22 May 2021 09:40:53 +0000 (11:40 +0200)
[ Upstream commit e1364711359f3ced054bda9920477c8bf93b74c5 ]

In devloss timer handler and in backend calls to terminate remote port I/O,
there is logic to walk through all active IOCBs and validate them to
potentially trigger an abort request. This logic is causing illegal memory
accesses which leads to a crash. Abort IOCBs, which may be on the list, do
not have an associated lpfc_io_buf struct. The driver is trying to map an
lpfc_io_buf struct on the IOCB and which results in a bogus address thus
the issue.

Fix by skipping over ABORT IOCBs (CLOSE IOCBs are ABORTS that don't send
ABTS) in the IOCB scan logic.

Link: https://lore.kernel.org/r/20210421234433.102079-1-jsmart2021@gmail.com
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/lpfc/lpfc_sli.c

index 3e5c0718555adb3413f0f2fa7db93464a0f33a22..bf171ef61abd5eb83125f7b3375629cb3d679ae3 100644 (file)
@@ -11590,13 +11590,20 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
                           lpfc_ctx_cmd ctx_cmd)
 {
        struct lpfc_io_buf *lpfc_cmd;
+       IOCB_t *icmd = NULL;
        int rc = 1;
 
        if (iocbq->vport != vport)
                return rc;
 
-       if (!(iocbq->iocb_flag &  LPFC_IO_FCP) ||
-           !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ))
+       if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
+           !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ) ||
+             iocbq->iocb_flag & LPFC_DRIVER_ABORTED)
+               return rc;
+
+       icmd = &iocbq->iocb;
+       if (icmd->ulpCommand == CMD_ABORT_XRI_CN ||
+           icmd->ulpCommand == CMD_CLOSE_XRI_CN)
                return rc;
 
        lpfc_cmd = container_of(iocbq, struct lpfc_io_buf, cur_iocbq);