Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753571AbeAAO5z (ORCPT + 1 other); Mon, 1 Jan 2018 09:57:55 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:46416 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932791AbeAAOo2 (ORCPT ); Mon, 1 Jan 2018 09:44:28 -0500 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jarod Wilson , Bert Kenward , "David S. Miller" Subject: [PATCH 4.14 095/146] sfc: pass valid pointers from efx_enqueue_unwind Date: Mon, 1 Jan 2018 15:38:06 +0100 Message-Id: <20180101140137.734283683@linuxfoundation.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180101140123.743014891@linuxfoundation.org> References: <20180101140123.743014891@linuxfoundation.org> User-Agent: quilt/0.65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Bert Kenward [ Upstream commit d4a7a8893d4cdbc89d79ac4aa704bf8d4b67b368 ] The bytes_compl and pkts_compl pointers passed to efx_dequeue_buffers cannot be NULL. Add a paranoid warning to check this condition and fix the one case where they were NULL. efx_enqueue_unwind() is called very rarely, during error handling. Without this fix it would fail with a NULL pointer dereference in efx_dequeue_buffer, with efx_enqueue_skb in the call stack. Fixes: e9117e5099ea ("sfc: Firmware-Assisted TSO version 2") Reported-by: Jarod Wilson Signed-off-by: Bert Kenward Tested-by: Jarod Wilson Acked-by: Jarod Wilson Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/sfc/tx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c @@ -77,6 +77,7 @@ static void efx_dequeue_buffer(struct ef } if (buffer->flags & EFX_TX_BUF_SKB) { + EFX_WARN_ON_PARANOID(!pkts_compl || !bytes_compl); (*pkts_compl)++; (*bytes_compl) += buffer->skb->len; dev_consume_skb_any((struct sk_buff *)buffer->skb); @@ -426,12 +427,14 @@ static int efx_tx_map_data(struct efx_tx static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) { struct efx_tx_buffer *buffer; + unsigned int bytes_compl = 0; + unsigned int pkts_compl = 0; /* Work backwards until we hit the original insert pointer value */ while (tx_queue->insert_count != tx_queue->write_count) { --tx_queue->insert_count; buffer = __efx_tx_queue_get_insert_buffer(tx_queue); - efx_dequeue_buffer(tx_queue, buffer, NULL, NULL); + efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl); } }