From patchwork Sat Apr 22 00:49:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Smart X-Patchwork-Id: 9694019 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6A81D6038D for ; Sat, 22 Apr 2017 00:49:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 48A7E2867D for ; Sat, 22 Apr 2017 00:49:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2A0B32868C; Sat, 22 Apr 2017 00:49:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9495D2867D for ; Sat, 22 Apr 2017 00:49:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1042942AbdDVAtR (ORCPT ); Fri, 21 Apr 2017 20:49:17 -0400 Received: from mail-oi0-f66.google.com ([209.85.218.66]:33132 "EHLO mail-oi0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1042941AbdDVAtQ (ORCPT ); Fri, 21 Apr 2017 20:49:16 -0400 Received: by mail-oi0-f66.google.com with SMTP id a189so24198260oib.0; Fri, 21 Apr 2017 17:49:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=hhSIL22i1JLH3SCMc76Pv+fvzYQEChE9/yuu2duuds8=; b=RqrW+X7wgqYRwkzdXHG/PkBHAdw5cChE0rnNbgDA0HZ06Z7PfqWk6ejML2WpdJ0qBb yFCcDGo1PHwuGb1ga5UNPobkqCi12YpPjnPZLHdnEEGPdVYZoDv9yyO+1PWRfUhI21c3 oKWblj3K+H61FK3tVH9dX7q13Wpr8QYZR/adm2SKFWb6ORWMmMRN3jEup3/F0l3NLi8R 5PEJ7X9AOmnFK0CS1NNIJCKMW4ty/tufinnpV+RJUjQg6EYzML7lqXN9H69s65ufX/MN RalQ9QAbkfbw4pZfNgRTEr6g5g/e1rQlaKTj1ATk6b+Z2cg7n7mcAfdZfq3SbKvXDUWU v20w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=hhSIL22i1JLH3SCMc76Pv+fvzYQEChE9/yuu2duuds8=; b=enjdkcil4ST5iLJ7bgxU8r2ScpZT3JClIzJB+3roEZLUD9C9+MxfMMQv7rUCvsdh8e u+uhhsk1pIxVp89lVr/Cq6GIKIbHZFeTkuCc8K+NrjVhBbRJfC7L6dmCZ3RuuKR/JmEG TjbXnfc8klNo8JklI6Jtd2snO0Hofm/n5MujfnJv6nU8lFc+mjukFN2wDlwIfgOWDSQ/ ulfpW24OthYohaQGSw/HDikilVH/dy2dzPNpuWO1AmTO1BeXnYrndPy5Rd9r3uIlrpzF zAHdiRXCr3pJl4ABb3G55zgWbe9M07JajatJIcB+AXmToSN9HBaHwb2eii6bHGw+qyPS 2xTQ== X-Gm-Message-State: AN3rC/7NFJgJQ9YD1AZTDyleVXlnv8ipq8HeB9zPrfR1aO8bzX2MPt+s 5LVBsnU4Q9vK4w== X-Received: by 10.202.81.151 with SMTP id f145mr8642503oib.164.1492822155298; Fri, 21 Apr 2017 17:49:15 -0700 (PDT) Received: from flash.localdomain (ip68-5-29-33.oc.oc.cox.net. [68.5.29.33]) by smtp.gmail.com with ESMTPSA id e46sm4867800otc.17.2017.04.21.17.49.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Apr 2017 17:49:14 -0700 (PDT) From: jsmart2021@gmail.com To: linux-scsi@vger.kernel.org, linux-nvme@lists.infradead.org, sagi@grimberg.me, emilne@redhat.com, jthumshirn@suse.de, linux-block@vger.kernel.org, martin.petersen@oracle.com Cc: James Smart , Dick Kennedy , James Smart Subject: [PATCH] lpfc: Fix memory corruption of the lpfc_ncmd->list pointers Date: Fri, 21 Apr 2017 17:49:08 -0700 Message-Id: <20170422004908.24261-1-jsmart2021@gmail.com> X-Mailer: git-send-email 2.9.3 Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: James Smart lpfc was changing the private pointer that is set/maintained by the nvme_fc transport. This caused two issues: a) the transport, on teardown may erroneous attempt to free whatever address was set; and b) lfpc uses any value set in lpfc_nvme_fcp_abort() and assumes its a valid io request. Correct issue by properly defining a context structure for lpfc. Lpfc also updated to clear the private context structure on io completion. Since this bug caused scrutiny of the way lpfc moves local request structures between lists, also cleaned up list_del()'s to list_del_inits()'s. This is a nvme-specific bug. The patch was cut against the linux-block tree, for-4.12/block tree. It should be pulled in through that tree. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nvme.c | 17 +++++++++++------ drivers/scsi/lpfc/lpfc_nvme.h | 4 ++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index f98cbc2..8008c82 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -761,6 +761,7 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, struct nvme_fc_cmd_iu *cp; struct lpfc_nvme_rport *rport; struct lpfc_nodelist *ndlp; + struct lpfc_nvme_fcpreq_priv *freqpriv; unsigned long flags; uint32_t code; uint16_t cid, sqhd, data; @@ -918,6 +919,8 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, phba->cpucheck_cmpl_io[lpfc_ncmd->cpu]++; } #endif + freqpriv = nCmd->private; + freqpriv->nvme_buf = NULL; nCmd->done(nCmd); spin_lock_irqsave(&phba->hbalock, flags); @@ -1214,6 +1217,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, struct lpfc_nvme_buf *lpfc_ncmd; struct lpfc_nvme_rport *rport; struct lpfc_nvme_qhandle *lpfc_queue_info; + struct lpfc_nvme_fcpreq_priv *freqpriv = pnvme_fcreq->private; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS uint64_t start = 0; #endif @@ -1292,7 +1296,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, * Do not let the IO hang out forever. There is no midlayer issuing * an abort so inform the FW of the maximum IO pending time. */ - pnvme_fcreq->private = (void *)lpfc_ncmd; + freqpriv->nvme_buf = lpfc_ncmd; lpfc_ncmd->nvmeCmd = pnvme_fcreq; lpfc_ncmd->nrport = rport; lpfc_ncmd->ndlp = ndlp; @@ -1422,6 +1426,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, struct lpfc_nvme_buf *lpfc_nbuf; struct lpfc_iocbq *abts_buf; struct lpfc_iocbq *nvmereq_wqe; + struct lpfc_nvme_fcpreq_priv *freqpriv = pnvme_fcreq->private; union lpfc_wqe *abts_wqe; unsigned long flags; int ret_val; @@ -1484,7 +1489,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, return; } - lpfc_nbuf = (struct lpfc_nvme_buf *)pnvme_fcreq->private; + lpfc_nbuf = freqpriv->nvme_buf; if (!lpfc_nbuf) { spin_unlock_irqrestore(&phba->hbalock, flags); lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_ABTS, @@ -1637,7 +1642,7 @@ static struct nvme_fc_port_template lpfc_nvme_template = { .local_priv_sz = sizeof(struct lpfc_nvme_lport), .remote_priv_sz = sizeof(struct lpfc_nvme_rport), .lsrqst_priv_sz = 0, - .fcprqst_priv_sz = 0, + .fcprqst_priv_sz = sizeof(struct lpfc_nvme_fcpreq_priv), }; /** @@ -2068,7 +2073,7 @@ lpfc_get_nvme_buf(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) if (lpfc_test_rrq_active(phba, ndlp, lpfc_ncmd->cur_iocbq.sli4_lxritag)) continue; - list_del(&lpfc_ncmd->list); + list_del_init(&lpfc_ncmd->list); found = 1; break; } @@ -2083,7 +2088,7 @@ lpfc_get_nvme_buf(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) if (lpfc_test_rrq_active( phba, ndlp, lpfc_ncmd->cur_iocbq.sli4_lxritag)) continue; - list_del(&lpfc_ncmd->list); + list_del_init(&lpfc_ncmd->list); found = 1; break; } @@ -2542,7 +2547,7 @@ lpfc_sli4_nvme_xri_aborted(struct lpfc_hba *phba, &phba->sli4_hba.lpfc_abts_nvme_buf_list, list) { if (lpfc_ncmd->cur_iocbq.sli4_xritag == xri) { - list_del(&lpfc_ncmd->list); + list_del_init(&lpfc_ncmd->list); lpfc_ncmd->flags &= ~LPFC_SBUF_XBUSY; lpfc_ncmd->status = IOSTAT_SUCCESS; spin_unlock( diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h index 2582f46..ec32f45 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.h +++ b/drivers/scsi/lpfc/lpfc_nvme.h @@ -97,3 +97,7 @@ struct lpfc_nvme_buf { uint64_t ts_data_nvme; #endif }; + +struct lpfc_nvme_fcpreq_priv { + struct lpfc_nvme_buf *nvme_buf; +};