From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 985B1C33CB6 for ; Thu, 16 Jan 2020 18:16:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 75ECE22522 for ; Thu, 16 Jan 2020 18:16:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1579198565; bh=RIjjSlgXFljZ+ANBVrJotX5XLZbHnKiqcXVztCjBkvM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=aJ42acVQ7WIaXOPZ5H+dBS3RYWVvQCoRSG96497RCKSQwG75X7eGTTlVU3JzX7CZ9 tSgqLUvCJtu+Lsf+vuYbOgm4ZCay7TbR8AlHWJwLMc5QgtUhh0l5CI0KO7gmFy1IT3 sugZgib8qKaySK0uEfRw6RYqIoC5UNJ6V/m6Enrw= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392764AbgAPR3e (ORCPT ); Thu, 16 Jan 2020 12:29:34 -0500 Received: from mail.kernel.org ([198.145.29.99]:41474 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392752AbgAPR3e (ORCPT ); Thu, 16 Jan 2020 12:29:34 -0500 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 7785024724; Thu, 16 Jan 2020 17:29:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1579195773; bh=RIjjSlgXFljZ+ANBVrJotX5XLZbHnKiqcXVztCjBkvM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z+HQbpTDiyrmLJXlUaiqVCAyikJ7dBR+hDIbSQ0lf8Kxa9gGonCiVMq9oOgRVfY5L JBPSdfw5MYJNZbhcZgSSOBV0fGxGJWOZ1d8bwBpnGUsk4QCl+I5Oy51mv69PhPc4pU 7btsQ2K+lTLf3o4JqCQ9aQBuW1IOMBqkSNx/mbA0= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Nicolas Boichat , Wen Gong , Kalle Valo , Sasha Levin , ath10k@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH AUTOSEL 4.14 299/371] ath10k: adjust skb length in ath10k_sdio_mbox_rx_packet Date: Thu, 16 Jan 2020 12:22:51 -0500 Message-Id: <20200116172403.18149-242-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200116172403.18149-1-sashal@kernel.org> References: <20200116172403.18149-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Nicolas Boichat [ Upstream commit b7139960832eb56fa15d390a4b5c8c5739bd0d1a ] When the FW bundles multiple packets, pkt->act_len may be incorrect as it refers to the first packet only (however, the FW will only bundle packets that fit into the same pkt->alloc_len). Before this patch, the skb length would be set (incorrectly) to pkt->act_len in ath10k_sdio_mbox_rx_packet, and then later manually adjusted in ath10k_sdio_mbox_rx_process_packet. The first problem is that ath10k_sdio_mbox_rx_process_packet does not use proper skb_put commands to adjust the length (it directly changes skb->len), so we end up with a mismatch between skb->head + skb->tail and skb->data + skb->len. This is quite serious, and causes corruptions in the TCP stack, as the stack tries to coalesce packets, and relies on skb->tail being correct (that is, skb_tail_pointer must point to the first byte_after_ the data). Instead of re-adjusting the size in ath10k_sdio_mbox_rx_process_packet, this moves the code to ath10k_sdio_mbox_rx_packet, and also add a bounds check, as skb_put would crash the kernel if not enough space is available. Tested with QCA6174 SDIO with firmware WLAN.RMH.4.4.1-00007-QCARMSWP-1. Fixes: 8530b4e7b22bc3b ("ath10k: sdio: set skb len for all rx packets") Signed-off-by: Nicolas Boichat Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath10k/sdio.c | 29 +++++++++++++++++++------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c index 0a1248ebccf5..f49b21b137c1 100644 --- a/drivers/net/wireless/ath/ath10k/sdio.c +++ b/drivers/net/wireless/ath/ath10k/sdio.c @@ -392,16 +392,11 @@ static int ath10k_sdio_mbox_rx_process_packet(struct ath10k *ar, struct ath10k_htc_hdr *htc_hdr = (struct ath10k_htc_hdr *)skb->data; bool trailer_present = htc_hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT; enum ath10k_htc_ep_id eid; - u16 payload_len; u8 *trailer; int ret; - payload_len = le16_to_cpu(htc_hdr->len); - skb->len = payload_len + sizeof(struct ath10k_htc_hdr); - if (trailer_present) { - trailer = skb->data + sizeof(*htc_hdr) + - payload_len - htc_hdr->trailer_len; + trailer = skb->data + skb->len - htc_hdr->trailer_len; eid = pipe_id_to_eid(htc_hdr->eid); @@ -635,13 +630,31 @@ static int ath10k_sdio_mbox_rx_packet(struct ath10k *ar, { struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar); struct sk_buff *skb = pkt->skb; + struct ath10k_htc_hdr *htc_hdr; int ret; ret = ath10k_sdio_readsb(ar, ar_sdio->mbox_info.htc_addr, skb->data, pkt->alloc_len); + if (ret) + goto out; + + /* Update actual length. The original length may be incorrect, + * as the FW will bundle multiple packets as long as their sizes + * fit within the same aligned length (pkt->alloc_len). + */ + htc_hdr = (struct ath10k_htc_hdr *)skb->data; + pkt->act_len = le16_to_cpu(htc_hdr->len) + sizeof(*htc_hdr); + if (pkt->act_len > pkt->alloc_len) { + ath10k_warn(ar, "rx packet too large (%zu > %zu)\n", + pkt->act_len, pkt->alloc_len); + ret = -EMSGSIZE; + goto out; + } + + skb_put(skb, pkt->act_len); + +out: pkt->status = ret; - if (!ret) - skb_put(skb, pkt->act_len); return ret; } -- 2.20.1