netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Yan-Hsuan Chuang <yhchuang@realtek.com>,
	Kalle Valo <kvalo@codeaurora.org>,
	Sasha Levin <sashal@kernel.org>,
	linux-wireless@vger.kernel.org, netdev@vger.kernel.org
Subject: [PATCH AUTOSEL 5.4 022/205] rtw88: fix beaconing mode rsvd_page memory violation issue
Date: Thu, 16 Jan 2020 11:39:57 -0500	[thread overview]
Message-ID: <20200116164300.6705-22-sashal@kernel.org> (raw)
In-Reply-To: <20200116164300.6705-1-sashal@kernel.org>

From: Yan-Hsuan Chuang <yhchuang@realtek.com>

[ Upstream commit c3594559f49c601d410dee4b767c3536a5535bfd ]

When downloading the reserved page, the first page always contains
a beacon for the firmware to reference. For non-beaconing modes such
as station mode, also put a blank skb with length=1.

And for the beaconing modes, driver will get a real beacon with a
length approximate to the page size. But as the beacon is always put
at the first page, it does not need a tx_desc, because the TX path
will generate one when TXing the reserved page to the hardware. So we
could allocate a buffer with a size smaller than the reserved page,
when using memcpy() to copy the content of reserved page to the buffer,
the over-sized reserved page will violate the kernel memory.

To fix it, add the tx_desc before memcpy() the reserved packets to
the buffer, then we can get SKBs with correct length when counting
the pages in total. And for page 0, count the extra tx_desc_sz that
the TX path will generate. This way, the first beacon that allocated
without tx_desc can be counted with the extra tx_desc_sz to get
actual pages it requires.

Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver")
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/realtek/rtw88/fw.c | 52 ++++++++++++++++++++-----
 1 file changed, 43 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index b082e2cc95f5..35dbdb3c4f1e 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -498,9 +498,6 @@ static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u8 page_size,
 {
 	struct sk_buff *skb = rsvd_pkt->skb;
 
-	if (rsvd_pkt->add_txdesc)
-		rtw_fill_rsvd_page_desc(rtwdev, skb);
-
 	if (page >= 1)
 		memcpy(buf + page_margin + page_size * (page - 1),
 		       skb->data, skb->len);
@@ -625,16 +622,37 @@ static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev,
 	list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, list) {
 		iter = rtw_get_rsvd_page_skb(hw, vif, rsvd_pkt->type);
 		if (!iter) {
-			rtw_err(rtwdev, "fail to build rsvd packet\n");
+			rtw_err(rtwdev, "failed to build rsvd packet\n");
 			goto release_skb;
 		}
+
+		/* Fill the tx_desc for the rsvd pkt that requires one.
+		 * And iter->len will be added with size of tx_desc_sz.
+		 */
+		if (rsvd_pkt->add_txdesc)
+			rtw_fill_rsvd_page_desc(rtwdev, iter);
+
 		rsvd_pkt->skb = iter;
 		rsvd_pkt->page = total_page;
-		if (rsvd_pkt->add_txdesc)
+
+		/* Reserved page is downloaded via TX path, and TX path will
+		 * generate a tx_desc at the header to describe length of
+		 * the buffer. If we are not counting page numbers with the
+		 * size of tx_desc added at the first rsvd_pkt (usually a
+		 * beacon, firmware default refer to the first page as the
+		 * content of beacon), we could generate a buffer which size
+		 * is smaller than the actual size of the whole rsvd_page
+		 */
+		if (total_page == 0) {
+			if (rsvd_pkt->type != RSVD_BEACON) {
+				rtw_err(rtwdev, "first page should be a beacon\n");
+				goto release_skb;
+			}
 			total_page += rtw_len_to_page(iter->len + tx_desc_sz,
 						      page_size);
-		else
+		} else {
 			total_page += rtw_len_to_page(iter->len, page_size);
+		}
 	}
 
 	if (total_page > rtwdev->fifo.rsvd_drv_pg_num) {
@@ -647,13 +665,24 @@ static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev,
 	if (!buf)
 		goto release_skb;
 
+	/* Copy the content of each rsvd_pkt to the buf, and they should
+	 * be aligned to the pages.
+	 *
+	 * Note that the first rsvd_pkt is a beacon no matter what vif->type.
+	 * And that rsvd_pkt does not require tx_desc because when it goes
+	 * through TX path, the TX path will generate one for it.
+	 */
 	list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, list) {
 		rtw_rsvd_page_list_to_buf(rtwdev, page_size, page_margin,
 					  page, buf, rsvd_pkt);
-		page += rtw_len_to_page(rsvd_pkt->skb->len, page_size);
-	}
-	list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, list)
+		if (page == 0)
+			page += rtw_len_to_page(rsvd_pkt->skb->len +
+						tx_desc_sz, page_size);
+		else
+			page += rtw_len_to_page(rsvd_pkt->skb->len, page_size);
+
 		kfree_skb(rsvd_pkt->skb);
+	}
 
 	return buf;
 
@@ -706,6 +735,11 @@ int rtw_fw_download_rsvd_page(struct rtw_dev *rtwdev, struct ieee80211_vif *vif)
 		goto free;
 	}
 
+	/* The last thing is to download the *ONLY* beacon again, because
+	 * the previous tx_desc is to describe the total rsvd page. Download
+	 * the beacon again to replace the TX desc header, and we will get
+	 * a correct tx_desc for the beacon in the rsvd page.
+	 */
 	ret = rtw_download_beacon(rtwdev, vif);
 	if (ret) {
 		rtw_err(rtwdev, "failed to download beacon\n");
-- 
2.20.1


  parent reply	other threads:[~2020-01-16 16:44 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20200116164300.6705-1-sashal@kernel.org>
2020-01-16 16:39 ` [PATCH AUTOSEL 5.4 008/205] mt7601u: fix bbp version check in mt7601u_wait_bbp_ready Sasha Levin
2020-01-16 16:39 ` [PATCH AUTOSEL 5.4 018/205] cw1200: Fix a signedness bug in cw1200_load_firmware() Sasha Levin
2020-01-16 16:39 ` Sasha Levin [this message]
2020-01-16 16:39 ` [PATCH AUTOSEL 5.4 023/205] rtw88: fix error handling when setup efuse info Sasha Levin
2020-01-16 16:40 ` [PATCH AUTOSEL 5.4 028/205] net: phy: broadcom: Fix RGMII delays configuration for BCM54210E Sasha Levin
2020-01-16 16:40 ` [PATCH AUTOSEL 5.4 030/205] dpaa2-eth: Fix minor bug in ethtool stats reporting Sasha Levin
2020-01-16 16:40 ` [PATCH AUTOSEL 5.4 049/205] net: netsec: Correct dma sync for XDP_TX frames Sasha Levin
2020-01-16 16:40 ` [PATCH AUTOSEL 5.4 057/205] rtlwifi: Remove unnecessary NULL check in rtl_regd_init Sasha Levin
2020-01-16 16:40 ` [PATCH AUTOSEL 5.4 058/205] xprtrdma: Connection becomes unstable after a reconnect Sasha Levin
2020-01-16 16:40 ` [PATCH AUTOSEL 5.4 059/205] xprtrdma: Fix MR list handling Sasha Levin
2020-01-16 16:40 ` [PATCH AUTOSEL 5.4 064/205] iwlwifi: mvm: consider ieee80211 station max amsdu value Sasha Levin
2020-01-16 16:40 ` [PATCH AUTOSEL 5.4 077/205] libbpf: Fix compatibility for kernels without need_wakeup Sasha Levin
2020-01-16 16:40 ` [PATCH AUTOSEL 5.4 080/205] libbpf: Don't use kernel-side u32 type in xsk.c Sasha Levin
2020-01-16 16:40 ` [PATCH AUTOSEL 5.4 083/205] SUNRPC: Fix svcauth_gss_proxy_init() Sasha Levin
2020-01-16 16:40 ` [PATCH AUTOSEL 5.4 084/205] rtw88: fix potential read outside array boundary Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 087/205] dpaa_eth: perform DMA unmapping before read Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 088/205] dpaa_eth: avoid timestamp read on error paths Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 096/205] net: openvswitch: don't unlock mutex when changing the user_features fails Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 102/205] hv_netvsc: flag software created hash value Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 104/205] rt2800: remove errornous duplicate condition Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 107/205] net: neigh: use long type to store jiffies delta Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 108/205] tipc: reduce sensitive to retransmit failures Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 109/205] net: axienet: Fix error return code in axienet_probe() Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 111/205] libbpf: Fix memory leak/double free issue Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 112/205] libbpf: Fix potential overflow issue Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 113/205] libbpf: Fix another potential overflow issue in bpf_prog_linfo Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 114/205] libbpf: Make btf__resolve_size logic always check size error condition Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 121/205] packet: fix data-race in fanout_flow_is_huge() Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 137/205] tipc: update mon's self addr when node addr generated Sasha Levin
2020-01-16 16:41 ` [PATCH AUTOSEL 5.4 142/205] iwlwifi: mvm: fix support for single antenna diversity Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 148/205] netfilter: nf_tables_offload: release flow_rule on error from commit path Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 149/205] SUNRPC: Fix another issue with MIC buffer space Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 155/205] libbpf: Fix call relocation offset calculation bug Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 159/205] mt76: mt76u: rely on usb_interface instead of usb_dev Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 164/205] bpf: skmsg, fix potential psock NULL pointer dereference Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 165/205] SUNRPC: Fix backchannel latency metrics Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 171/205] ice: fix stack leakage Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 172/205] xdp: Fix cleanup on map free for devmap_hash map type Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 179/205] bpf: Support pre-2.25-binutils objcopy for vmlinux BTF Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 180/205] libbpf: Fix Makefile' libbpf symbol mismatch diagnostic Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 181/205] ath9k: use iowrite32 over __raw_writel Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 183/205] tipc: fix potential memory leak in __tipc_sendmsg() Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 184/205] tipc: fix wrong socket reference counter after tipc_sk_timeout() returns Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 185/205] tipc: fix wrong timeout input for tipc_wait_for_cond() Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 186/205] bpf: Force .BTF section start to zero when dumping from vmlinux Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 188/205] sch_cake: Add missing NLA policy entry TCA_CAKE_SPLIT_GSO Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 191/205] samples/bpf: Fix broken xdp_rxq_info due to map order assumptions Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 195/205] net/mlx5e: Fix free peer_flow when refcount is 0 Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 197/205] net-sysfs: Call dev_hold always in netdev_queue_add_kobject Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 201/205] tipc: fix potential hanging after b/rcast changing Sasha Levin
2020-01-16 16:42 ` [PATCH AUTOSEL 5.4 202/205] tipc: fix retrans failure due to wrong destination Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200116164300.6705-22-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=kvalo@codeaurora.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=yhchuang@realtek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).