Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp2501510imm; Mon, 24 Sep 2018 05:33:00 -0700 (PDT) X-Google-Smtp-Source: ACcGV61U/iXuhdBBoN+jkfqV0U4xsQbIvZ7WxNVgelyt4rt1Og3dS3gso4dnT+lszNYI0vPLtujD X-Received: by 2002:a17:902:6b47:: with SMTP id g7-v6mr10732966plt.128.1537792380687; Mon, 24 Sep 2018 05:33:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1537792380; cv=none; d=google.com; s=arc-20160816; b=dRzzTF0z2XL8dmFnWkp2+yOWS9/uLeV19p/oPkkCtu2rOjtcMzGEeVLxAgL5O+UuCU nxlV2MT72bTXvO7dLOZszvvW8CfGIfpHNvThGLAofXA0lD2LiHTnPemR20bf6ftnyZhn xjgJnDdlI+65eM4HW9ZZpHu0u107ZkfUCkRvA3jJQPx1/HCCCl5qtjvK2P4JXtaiZP/r QyaRv5dtlptFiVvmB/Yd+QjQVhxE02jdKRcW3jnHSJUhFwVI/PIE/3bGXA+TWoODQs3D seXfe3kSck7OQvLR1Fc50EOanDo+/Y3cq+nMwCEWHiOmyeAkMQaIc3WCk0aRmKligblQ 6Jhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from; bh=c6kc3AUN0q/HG4OyRPFP3KK5a2K24ZS6n3tSV9/la98=; b=Bpf4B0s5EI9eKVhRIAyIUffobqJTKEA5iOk8aKmrej/DQNrZUbuzTd6Qjma1lU4npa 9ZlR21AL+TRAejpIUO5b1z981kRXnx6DvH+wycA95veCWHHTCPJHDmBkJl+giDh7Sg0y vyd/aU7V9aKnSySG48opv1ICBX+anTPCBq/nhDYXEHLajWkK1fVOhRSt6q0ojhZum1FA 24gsKI3LeiTzqJBQtnMlyNtzt0S2EfVV/RhwY08fwXMq6z5etn1XxyycCyaj/DYMrRp9 drQXjkm/0jo974eS0vw/94I7/Ekw3JbBYRYrOum+0YJ9Soc4J1E8h8g/awpLlpLGeASM sTrg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q1-v6si35131697plb.35.2018.09.24.05.32.45; Mon, 24 Sep 2018 05:33:00 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388038AbeIXSdY (ORCPT + 99 others); Mon, 24 Sep 2018 14:33:24 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:57970 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732138AbeIXSdX (ORCPT ); Mon, 24 Sep 2018 14:33:23 -0400 Received: from localhost (ip-213-127-77-73.ip.prioritytelecom.net [213.127.77.73]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id CB7741099; Mon, 24 Sep 2018 12:31:27 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jakub Kicinski , Dirk van der Merwe , "David S. Miller" , Sasha Levin Subject: [PATCH 4.18 077/235] nfp: avoid buffer leak when FW communication fails Date: Mon, 24 Sep 2018 13:51:03 +0200 Message-Id: <20180924113112.848828428@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180924113103.999624566@linuxfoundation.org> References: <20180924113103.999624566@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jakub Kicinski [ Upstream commit 07300f774fec9519663a597987a4083225588be4 ] After device is stopped we reset the rings by moving all free buffers to positions [0, cnt - 2], and clear the position cnt - 1 in the ring. We then proceed to clear the read/write pointers. This means that if we try to reset the ring again the code will assume that the next to fill buffer is at position 0 and swap it with cnt - 1. Since we previously cleared position cnt - 1 it will lead to leaking the first buffer and leaving ring in a bad state. This scenario can only happen if FW communication fails, in which case the ring will never be used again, so the fact it's in a bad state will not be noticed. Buffer leak is the only problem. Don't try to move buffers in the ring if the read/write pointers indicate the ring was never used or have already been reset. nfp_net_clear_config_and_disable() is now fully idempotent. Found by code inspection, FW communication failures are very rare, and reconfiguring a live device is not common either, so it's unlikely anyone has ever noticed the leak. Signed-off-by: Jakub Kicinski Reviewed-by: Dirk van der Merwe Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -1093,7 +1093,7 @@ static bool nfp_net_xdp_complete(struct * @dp: NFP Net data path struct * @tx_ring: TX ring structure * - * Assumes that the device is stopped + * Assumes that the device is stopped, must be idempotent. */ static void nfp_net_tx_ring_reset(struct nfp_net_dp *dp, struct nfp_net_tx_ring *tx_ring) @@ -1295,13 +1295,18 @@ static void nfp_net_rx_give_one(const st * nfp_net_rx_ring_reset() - Reflect in SW state of freelist after disable * @rx_ring: RX ring structure * - * Warning: Do *not* call if ring buffers were never put on the FW freelist - * (i.e. device was not enabled)! + * Assumes that the device is stopped, must be idempotent. */ static void nfp_net_rx_ring_reset(struct nfp_net_rx_ring *rx_ring) { unsigned int wr_idx, last_idx; + /* wr_p == rd_p means ring was never fed FL bufs. RX rings are always + * kept at cnt - 1 FL bufs. + */ + if (rx_ring->wr_p == 0 && rx_ring->rd_p == 0) + return; + /* Move the empty entry to the end of the list */ wr_idx = D_IDX(rx_ring, rx_ring->wr_p); last_idx = rx_ring->cnt - 1; @@ -2524,6 +2529,8 @@ static void nfp_net_vec_clear_ring_data( /** * nfp_net_clear_config_and_disable() - Clear control BAR and disable NFP * @nn: NFP Net device to reconfigure + * + * Warning: must be fully idempotent. */ static void nfp_net_clear_config_and_disable(struct nfp_net *nn) {