diff options
author | Dick Kennedy <dick.kennedy@broadcom.com> | 2017-09-29 17:34:29 -0700 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-10-02 22:46:33 -0400 |
commit | 1234a6d54fed8a00091968c4eb2fb52e1cbb8e2e (patch) | |
tree | 443eb288638e1b2981fe88ff83ff47ed613b37c4 /drivers/scsi/lpfc/lpfc_bsg.c | |
parent | 401bb4169da655f3e5d28d0b208182e1ab60bf2a (diff) | |
download | linux-1234a6d54fed8a00091968c4eb2fb52e1cbb8e2e.tar.gz linux-1234a6d54fed8a00091968c4eb2fb52e1cbb8e2e.tar.bz2 linux-1234a6d54fed8a00091968c4eb2fb52e1cbb8e2e.zip |
scsi: lpfc: Fix crash receiving ELS while detaching driver
The driver crashes when attempting to use a freed ndpl pointer.
The pci_remove_one handler runs on a separate kernel thread. The order
of the removal is starting by freeing all of the ndlps and then
disabling interrupts. In between these two events the driver can still
receive an ELS and process it. When it tries to use the ndlp pointer
will be NULL
Change the order of the pci_remove_one vs disable interrupts so that
interrupts are disabled before the ndlp's are freed.
Cc: <stable@vger.kernel.org> # 4.12+
Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <james.smart@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_bsg.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_bsg.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index fe9e1c079c20..d89816222b23 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -2911,7 +2911,7 @@ static int lpfcdiag_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri, } } - if (!cmdiocbq || !rxbmp || !rxbpl || !rxbuffer) { + if (!cmdiocbq || !rxbmp || !rxbpl || !rxbuffer || !pring) { ret_val = -ENOMEM; goto err_post_rxbufs_exit; } @@ -5421,6 +5421,8 @@ lpfc_bsg_timeout(struct bsg_job *job) struct lpfc_iocbq *check_iocb, *next_iocb; pring = lpfc_phba_elsring(phba); + if (unlikely(!pring)) + return -EIO; /* if job's driver data is NULL, the command completed or is in the * the process of completing. In this case, return status to request |