Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4623921pxj; Wed, 12 May 2021 09:28:24 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyCEk6wEqGPeKPY8Y7c9rjByZ3uRiTwXrtN1l0dAxvJZ0OdQ5s2BDpYSuJsSs7pPRa6JS7/ X-Received: by 2002:a17:907:7243:: with SMTP id ds3mr37751616ejc.100.1620836903651; Wed, 12 May 2021 09:28:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620836903; cv=none; d=google.com; s=arc-20160816; b=kkihmElGoqzz8lFMITus5nGMMSfsZKqgAjkNkg6CeAI/CY0TK9uRqqEiVA9b+pvGkC xErv2yCpXbv3PVW6MIMJ/DVgllImysUQWu16pgAUGNhA336vJYZWld2tsZ8g+Nwlavfk 4eSE6c5aZj8NuAIvAn7wIngRynGSGzVqnOswING4bw68MFDow8laeqltbyS2sVWe4Hbj hCkWVBfWCYy2sq0mrudqxmbxoxJCpfc9DZMY6ujXTdpuILsgG4JpHr25udchAzWvzhqf 0QAlSRKpfljbgjjhlQuHYqFeJNaA/fChZMnUZz35j8+B1pS6Js6ehbmkxVL6NOUiyyl0 ftuQ== 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=oeKsuVG53q7o15hJ3Spio+/GzFmsakrVziqoOeRzB63qHKEgzdt4WMQdBgR/JmrI0b BFLKCGM7Gg5SucPhuvLjgW90TdKEIeTunRV+HW5KQ4LSnlZ/neGlsejaUY8m2NdFWJhO assN/I9eRgYFJAkXl7dvSV4StVo6zi1PHRsISTy/DL4jIfEU8SvuHxFa1wvNmiOt19b5 A/3TR9eSsHpVmN5wCSVPrUiZfFoAzMXOqbjlPqB8bFgv/nssNmMaY25wbPjqQQyKfUnq kGCnIpyMcNAOGWDcXH9DwcpAWogkC42H6rsovnNukoz/XrP2EvMJ0FKVANsvSpdLJG+w JgMA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=pu89jmfm; 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 t2si108103edd.569.2021.05.12.09.28.00; Wed, 12 May 2021 09:28:23 -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=pu89jmfm; 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 S240841AbhELQZp (ORCPT + 99 others); Wed, 12 May 2021 12:25:45 -0400 Received: from mail.kernel.org ([198.145.29.99]:45780 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233591AbhELPbS (ORCPT ); Wed, 12 May 2021 11:31:18 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9D8266197E; Wed, 12 May 2021 15:16:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620832579; bh=/2PZ05TWR4TOZ3n/k6GflWD5+nE/eKQ7UrY67WWXQHc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pu89jmfm2haE8QECOGOJEYeh8lUAn/l44T0U/TKcitbBskErvn/XGIXxcupaqP0NP hW9bJ83EWGVpInt0qH+wZaZCuLGw+EgBDxPwqbqLULGMfVrUficlFHjxbHsLaTxohB APxQjTjIWS0KIlVecAWdBZcnBCurZumDsiIXG2HI= 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.10 338/530] nvmet-tcp: fix a segmentation fault during io parsing error Date: Wed, 12 May 2021 16:47:28 +0200 Message-Id: <20210512144830.907288506@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210512144819.664462530@linuxfoundation.org> References: <20210512144819.664462530@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