diff options
author | James Smart <jsmart2021@gmail.com> | 2021-04-22 02:44:33 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2021-04-27 05:56:31 +0300 |
commit | e1364711359f3ced054bda9920477c8bf93b74c5 (patch) | |
tree | 355a5a302c79144b338b871f6631d0fb2645a78b | |
parent | 85367040511f8402d7e4054d8c17b053c75e33ff (diff) | |
download | linux-e1364711359f3ced054bda9920477c8bf93b74c5.tar.xz |
scsi: lpfc: Fix illegal memory access on Abort IOCBs
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>
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 06ccc0157bd8..579ac75dfe79 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -11804,13 +11804,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 || 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); |