mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-29 23:53:55 +08:00
scsi: lpfc: nvmet: avoid hang / use-after-free when destroying targetport
We cannot wait on a completion object in the lpfc_nvme_targetport structure in the _destroy_targetport() code path because the NVMe/fc transport will free that structure immediately after the .targetport_delete() callback. This results in a use-after-free, and a hang if slub_debug=FZPU is enabled. Fix this by putting the completion on the stack. Signed-off-by: Ewan D. Milne <emilne@redhat.com> Acked-by: James Smart <james.smart@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
7961cba6f7
commit
c41f59884b
@ -1003,7 +1003,8 @@ lpfc_nvmet_targetport_delete(struct nvmet_fc_target_port *targetport)
|
||||
struct lpfc_nvmet_tgtport *tport = targetport->private;
|
||||
|
||||
/* release any threads waiting for the unreg to complete */
|
||||
complete(&tport->tport_unreg_done);
|
||||
if (tport->phba->targetport)
|
||||
complete(tport->tport_unreg_cmp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1692,6 +1693,7 @@ lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba)
|
||||
struct lpfc_nvmet_tgtport *tgtp;
|
||||
struct lpfc_queue *wq;
|
||||
uint32_t qidx;
|
||||
DECLARE_COMPLETION_ONSTACK(tport_unreg_cmp);
|
||||
|
||||
if (phba->nvmet_support == 0)
|
||||
return;
|
||||
@ -1701,9 +1703,9 @@ lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba)
|
||||
wq = phba->sli4_hba.nvme_wq[qidx];
|
||||
lpfc_nvmet_wqfull_flush(phba, wq, NULL);
|
||||
}
|
||||
init_completion(&tgtp->tport_unreg_done);
|
||||
tgtp->tport_unreg_cmp = &tport_unreg_cmp;
|
||||
nvmet_fc_unregister_targetport(phba->targetport);
|
||||
wait_for_completion_timeout(&tgtp->tport_unreg_done, 5);
|
||||
wait_for_completion_timeout(&tport_unreg_cmp, 5);
|
||||
lpfc_nvmet_cleanup_io_context(phba);
|
||||
}
|
||||
phba->targetport = NULL;
|
||||
|
@ -34,7 +34,7 @@
|
||||
/* Used for NVME Target */
|
||||
struct lpfc_nvmet_tgtport {
|
||||
struct lpfc_hba *phba;
|
||||
struct completion tport_unreg_done;
|
||||
struct completion *tport_unreg_cmp;
|
||||
|
||||
/* Stats counters - lpfc_nvmet_unsol_ls_buffer */
|
||||
atomic_t rcv_ls_req_in;
|
||||
|
Loading…
Reference in New Issue
Block a user