Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4690417pxj; Wed, 12 May 2021 10:58:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyuaLuKARucM5VSU6yTeaw/9c2asZTuAFHY4s5yiikxUJNK9N3bi+XBxx+DNGFnc3Q6CWnY X-Received: by 2002:a05:6402:12c6:: with SMTP id k6mr44649796edx.372.1620842334014; Wed, 12 May 2021 10:58:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620842334; cv=none; d=google.com; s=arc-20160816; b=SD2ioMC83kyoiuVcwolVjxld3Jc93WS3EmUiaQKeY9Hi6+E0q+biZ20mBnuP967Nvn Yfyl62xzSMuxj8lhyUJOZ/1QSqG5qVgMhGOEyIzeV4GKFHI8YAT8JJNTzi/wwBsIF3Bf o3p6NdzalOevTMy0kq7qOGN40JkWEWbdt2Y9I8Pmj+yyRDx1BK5pFh4i6rIC6saQdcXq BoSyMvUQfgQh5vIaSDsMjnDuNyOKMJcLfIA5N2M2X56f4uqv75AXybhh1zXGPVpxSCtj Jx8vB76J79ec4mD7mqqeAmEtNgt4wE3W5Es4ibiXaunnL2ZJrh8frDAC6mZPJvwmHyVV pt2A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=uH1YWgQj6aL8qPvWjBd0Xwt8aP2Z495dahIqcC+3mIg=; b=miBpmud4KUHQSnmwB7kUUl14BGItGOqioEDFzrTrk+BLm/rbiPZmn3mYzigNgTwxEK o/QsX/Eb7B8iv+H5jN8n+YLZ2jK3bqnp9+bUJcqt9g29bLa3Y2oBs7QSDMV2k9eE0zUw nJbPaZdupVWLPLaVeYVF0lQtQUPZUZS8BGpIFfr2YCCC6Yzuf4h5+s25D+ATQ4j1upiv Zk0x8voKKucJN5D0KL231W/lQTiNbYkHYM0JbRaf7zTGGNSIlbEJ1qZ7/i1HAgu4aSub ZQscuTe9Zp7XB0KCO9HqQt3jiKSYmOurh7LP2A0lVa/HpDUJYG2kAjLZ5xOuCyXgx0xo VzaA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PO3WTS0A; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id o7si549421ejj.449.2021.05.12.10.58.30; Wed, 12 May 2021 10:58:54 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PO3WTS0A; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350013AbhELRrH (ORCPT + 99 others); Wed, 12 May 2021 13:47:07 -0400 Received: from mail.kernel.org ([198.145.29.99]:47838 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232990AbhELQNr (ORCPT ); Wed, 12 May 2021 12:13:47 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 70986619AC; Wed, 12 May 2021 15:41:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620834103; bh=/2PZ05TWR4TOZ3n/k6GflWD5+nE/eKQ7UrY67WWXQHc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PO3WTS0AeQxieq3xv8WRz7l7io4P/sr/uXaR0dbuDylmFHyFApGagzVDKrQJF55S3 sosjrWnjJqoK6YgfT5bAtBl2LMbJOcr9sbPz81mSeE2WxSZWV7n9Z4CKUP7ewDNUf5 rHOHnQv50rFfvcFYRgY1kW9+0wVoYdF8vO/MuFXM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Elad Grupi , Hou Pu , Sagi Grimberg , Christoph Hellwig , Sasha Levin Subject: [PATCH 5.11 375/601] nvmet-tcp: fix a segmentation fault during io parsing error Date: Wed, 12 May 2021 16:47:32 +0200 Message-Id: <20210512144840.146393428@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210512144827.811958675@linuxfoundation.org> References: <20210512144827.811958675@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Elad Grupi [ Upstream commit bdaf13279192c60b2b1fc99badef53b494fec055 ] In case there is an io that contains inline data and it goes to parsing error flow, command response will free command and iov before clearing the data on the socket buffer. This will delay the command response until receive flow is completed. Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver") Signed-off-by: Elad Grupi Signed-off-by: Hou Pu Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/target/tcp.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 218fd766dc74..d958b5da9b88 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -525,11 +525,36 @@ static void nvmet_tcp_queue_response(struct nvmet_req *req) struct nvmet_tcp_cmd *cmd = container_of(req, struct nvmet_tcp_cmd, req); struct nvmet_tcp_queue *queue = cmd->queue; + struct nvme_sgl_desc *sgl; + u32 len; + + if (unlikely(cmd == queue->cmd)) { + sgl = &cmd->req.cmd->common.dptr.sgl; + len = le32_to_cpu(sgl->length); + + /* + * Wait for inline data before processing the response. + * Avoid using helpers, this might happen before + * nvmet_req_init is completed. + */ + if (queue->rcv_state == NVMET_TCP_RECV_PDU && + len && len < cmd->req.port->inline_data_size && + nvme_is_write(cmd->req.cmd)) + return; + } llist_add(&cmd->lentry, &queue->resp_list); queue_work_on(queue_cpu(queue), nvmet_tcp_wq, &cmd->queue->io_work); } +static void nvmet_tcp_execute_request(struct nvmet_tcp_cmd *cmd) +{ + if (unlikely(cmd->flags & NVMET_TCP_F_INIT_FAILED)) + nvmet_tcp_queue_response(&cmd->req); + else + cmd->req.execute(&cmd->req); +} + static int nvmet_try_send_data_pdu(struct nvmet_tcp_cmd *cmd) { u8 hdgst = nvmet_tcp_hdgst_len(cmd->queue); @@ -961,7 +986,7 @@ static int nvmet_tcp_done_recv_pdu(struct nvmet_tcp_queue *queue) le32_to_cpu(req->cmd->common.dptr.sgl.length)); nvmet_tcp_handle_req_failure(queue, queue->cmd, req); - return -EAGAIN; + return 0; } ret = nvmet_tcp_map_data(queue->cmd); @@ -1104,10 +1129,8 @@ static int nvmet_tcp_try_recv_data(struct nvmet_tcp_queue *queue) return 0; } - if (!(cmd->flags & NVMET_TCP_F_INIT_FAILED) && - cmd->rbytes_done == cmd->req.transfer_len) { - cmd->req.execute(&cmd->req); - } + if (cmd->rbytes_done == cmd->req.transfer_len) + nvmet_tcp_execute_request(cmd); nvmet_prepare_receive_pdu(queue); return 0; @@ -1144,9 +1167,9 @@ static int nvmet_tcp_try_recv_ddgst(struct nvmet_tcp_queue *queue) goto out; } - if (!(cmd->flags & NVMET_TCP_F_INIT_FAILED) && - cmd->rbytes_done == cmd->req.transfer_len) - cmd->req.execute(&cmd->req); + if (cmd->rbytes_done == cmd->req.transfer_len) + nvmet_tcp_execute_request(cmd); + ret = 0; out: nvmet_prepare_receive_pdu(queue); -- 2.30.2