Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp3545597pxj; Mon, 24 May 2021 09:04:59 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyGKiqScWL6d6TKFhfHEEo0kiV5gat1H4CdxtZzffgFgdctU5p5vV3f5H7Fxm77Q8DfhwMP X-Received: by 2002:aa7:ca4d:: with SMTP id j13mr26248498edt.158.1621872299160; Mon, 24 May 2021 09:04:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621872299; cv=none; d=google.com; s=arc-20160816; b=G3zK5zpVlDdlT6YiE81NicVSAZig3Z17+zhrRUl46jVUJf3dEOE5bQaTLfoNqRZGMZ OsBNqRsYvNOIPghgjFRxub6tBM4yRBKatr3hSpLUguW5VmMadaZh4iMlO22Xs4VQWJRR 4ecj6xzAhdVWZ0P9jZTotJVryDN76QiWTjLJopNUhfb8lISWQlqwN9LVThg9Wvpd80GO 7/sizmNjoZUp0c0y5q4X5o2tyN4RxumSKq7Gr9vLqKi6UcBKJAnjQToiijc9iZeQgXZv 48/AyOczdUZDxeEXUSEXfCnlfMnynBKbPPhfJZ+cay8ExHfbl6pjUlfkQSsAtelePnpg 05rg== 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=JKLDI1Jc+m2J0NTTxHXnTbNLhZNBKAOoogY+6+uHVMA=; b=s90Ckj+P/pb4C+F577J4QdQVR3a1BVtJfSY+dXvVsXWpkieYn4b2bMjsAXwCC90pNC VvlN9fywSQScSqW9sDhf0gU8mIHDN7TIF3jL4PXiYmgSGcdfy2FCCKZmGx9npT1TN0q+ vEnboAONsLkck/Lbj+jjqG3Qt8JcRtPqcjQjHSm46tSCTXwgfX4//QwruqDRV3WMrrlZ enB9+McsYXzTBxRDZx6aIq3XuykCgnfuWg+SlmrYjCSSdCL+NToL+dWk6Sxalg6cQOJn KvnA3AqgtNUJZSTtk17XQ7uFb2rrKCH1w2uV+seq78LVgpTK4f88LvktSzqy/3KljC+T 0dgg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=HQyCZBPi; 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 yh21si17728936ejb.150.2021.05.24.09.04.20; Mon, 24 May 2021 09:04:59 -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=HQyCZBPi; 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 S235597AbhEXQBr (ORCPT + 99 others); Mon, 24 May 2021 12:01:47 -0400 Received: from mail.kernel.org ([198.145.29.99]:41102 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234285AbhEXPz2 (ORCPT ); Mon, 24 May 2021 11:55:28 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 12E4B6143C; Mon, 24 May 2021 15:41:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1621870905; bh=1thRWn/Ko8lZOPys+Us69FIXuUyvzd84Oklr9SZ8F9o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HQyCZBPiwWh3nSIfen4peIyqhCKcspVvTAnva9O6uGiJWg2XFy8TK40EIKI1FjgK8 Q0newV54exa2eSG8LuXF2wXgSOboeX9hr8BXxFE9SK+3SViQmyT0I/U+eWt7aGoX6L O8maBRf3GxKMKN0Dxy0R0Zg+GlL6Omn4kdinFU8E= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Narayan Ayalasomayajula , Anil Mishra , Keith Busch , Sagi Grimberg , Christoph Hellwig Subject: [PATCH 5.10 054/104] nvme-tcp: fix possible use-after-completion Date: Mon, 24 May 2021 17:25:49 +0200 Message-Id: <20210524152334.635527739@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210524152332.844251980@linuxfoundation.org> References: <20210524152332.844251980@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: Sagi Grimberg commit 825619b09ad351894d2c6fb6705f5b3711d145c7 upstream. Commit db5ad6b7f8cd ("nvme-tcp: try to send request in queue_rq context") added a second context that may perform a network send. This means that now RX and TX are not serialized in nvme_tcp_io_work and can run concurrently. While there is correct mutual exclusion in the TX path (where the send_mutex protect the queue socket send activity) RX activity, and more specifically request completion may run concurrently. This means we must guarantee that any mutation of the request state related to its lifetime, bytes sent must not be accessed when a completion may have possibly arrived back (and processed). The race may trigger when a request completion arrives, processed _and_ reused as a fresh new request, exactly in the (relatively short) window between the last data payload sent and before the request iov_iter is advanced. Consider the following race: 1. 16K write request is queued 2. The nvme command and the data is sent to the controller (in-capsule or solicited by r2t) 3. After the last payload is sent but before the req.iter is advanced, the controller sends back a completion. 4. The completion is processed, the request is completed, and reused to transfer a new request (write or read) 5. The new request is queued, and the driver reset the request parameters (nvme_tcp_setup_cmd_pdu). 6. Now context in (2) resumes execution and advances the req.iter ==> use-after-completion as this is already a new request. Fix this by making sure the request is not advanced after the last data payload send, knowing that a completion may have arrived already. An alternative solution would have been to delay the request completion or state change waiting for reference counting on the TX path, but besides adding atomic operations to the hot-path, it may present challenges in multi-stage R2T scenarios where a r2t handler needs to be deferred to an async execution. Reported-by: Narayan Ayalasomayajula Tested-by: Anil Mishra Reviewed-by: Keith Busch Cc: stable@vger.kernel.org # v5.8+ Signed-off-by: Sagi Grimberg Signed-off-by: Christoph Hellwig Signed-off-by: Greg Kroah-Hartman --- drivers/nvme/host/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -940,7 +940,6 @@ static int nvme_tcp_try_send_data(struct if (ret <= 0) return ret; - nvme_tcp_advance_req(req, ret); if (queue->data_digest) nvme_tcp_ddgst_update(queue->snd_hash, page, offset, ret); @@ -957,6 +956,7 @@ static int nvme_tcp_try_send_data(struct } return 1; } + nvme_tcp_advance_req(req, ret); } return -EAGAIN; }