Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp879570ybl; Fri, 24 Jan 2020 11:12:34 -0800 (PST) X-Google-Smtp-Source: APXvYqyr/O78SM+yLXP/N4IEVBc+TNMzPt5YMQHcOKRN0YgkC6PuEPZJonZBaMm4YuzVYEojbAua X-Received: by 2002:a9d:32c7:: with SMTP id u65mr3879173otb.224.1579893154747; Fri, 24 Jan 2020 11:12:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579893154; cv=none; d=google.com; s=arc-20160816; b=LRfjoz7Q9cvY73ZfSBuCU8RroMYfH6fecZIxDDIWoebFvya5fXD0TSTBwLOjJoELuE GnHMGmEvGRXpO7XvwB8/jNOhZIjTe7J26Ys6J08bqu8rEWIjAHN9/sdzXJlOJXqIJQKY X4fDKM03+T/hiWT/Zb4OhLEpQ03gCy2uQm4BR379qmoBz8j/NLpInggURIGrVp4O0bF/ zYvnb2cy77L5UXCQ18/bPJ7oFVuv6eES22+X+68pUD3F1kELsa6VG5s3R1801Jl+mvFJ wSypMGts5oX2qiM37ZSSSBE5wEgzIIWt3Sb2t7mYAWPeX8uMCrR7BsHet9VVBF7ZQx/A wruA== 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:dkim-signature; bh=jvjir41OhFF9gqanoNgad1Exj0qceSeRMzBLDPpytxc=; b=uQatAmw8qg0GzvVlLxK/PupN24Q5SPSIgUe3Si/HerlcF8Iu5jDlqsMBo4cN89b/99 czzrH4nHQtTXYgL2ZAbDup8sfNfC6TTtVc6K3wIJnQMspkHnlVFIjz3hPvNcz5bNr/DF 4wmWv9nFsllS0xNG0+an4Ca9nPL5dgSSg/2PsGl9Itv8RxAOop2It13QLmmfaNzFP6SJ XDb/RdozpgIN0f26DmT1bMbarf7MS78kqgmTUjmqXXy7cYzBbFnziRaoafRNkNaL7VAt dM/aEyy05F3baoTyooMCz/dKYdsaltTw67Q0MJbbOtIxAXnUJc/0Yz/HQs+Sj4S8nQla dwjw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=IQZf4j1X; 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 m13si3343771otq.1.2020.01.24.11.12.22; Fri, 24 Jan 2020 11:12:34 -0800 (PST) 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; dkim=pass header.i=@kernel.org header.s=default header.b=IQZf4j1X; 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 S2404474AbgAXLcn (ORCPT + 99 others); Fri, 24 Jan 2020 06:32:43 -0500 Received: from mail.kernel.org ([198.145.29.99]:51632 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404457AbgAXLch (ORCPT ); Fri, 24 Jan 2020 06:32:37 -0500 Received: from localhost (ip-213-127-102-57.ip.prioritytelecom.net [213.127.102.57]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 170AF20718; Fri, 24 Jan 2020 11:32:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1579865556; bh=P66QDkoviB+zUdkQgyk4I89vLSw6bqr4aQnRczcnrOQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IQZf4j1XZtRF9XnG3OdMIGEkLO72e2ky2RP4DYQUa7R0Bv/BrdVGGIuLwqu/hhUf4 b2qDmY/Y+piNXKFZEYbnusBdWdu1fnvyWDPskLFso7HhtQssSrKwT/K3xBUHkiJEOu zRsxm3D6fN8jFWs0HKtyHzaakHxUtkWopsiCfOk4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Nicolas Boichat , Wen Gong , Kalle Valo , Sasha Levin Subject: [PATCH 4.19 562/639] ath10k: adjust skb length in ath10k_sdio_mbox_rx_packet Date: Fri, 24 Jan 2020 10:32:12 +0100 Message-Id: <20200124093159.763231038@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200124093047.008739095@linuxfoundation.org> References: <20200124093047.008739095@linuxfoundation.org> User-Agent: quilt/0.66 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 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 686759b5613f2..0ecaba824fb28 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); @@ -638,13 +633,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