linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] rtw88: some fixes of hw_scan
@ 2022-01-21  7:08 Ping-Ke Shih
  2022-01-21  7:08 ` [PATCH 1/3] rtw88: check for validity before using a pointer Ping-Ke Shih
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Ping-Ke Shih @ 2022-01-21  7:08 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: linux-wireless, usama.anjum, phhuang

Since patch 2/3 and 3/3 is based on the first patch sent by Muhammad
https://lore.kernel.org/linux-wireless/YcWK1jxnd3vGdmCq@debian-BULLSEYE-live-builder-AMD64/
I put them together in this patchset, so we don't miss it.

The second patch is to enter idle mode by driver after hw_scan, and then
it can save more power. Third patch is to fix memory overrun and leak that
will lead kernel crash.

Muhammad Usama Anjum (1):
  rtw88: check for validity before using a pointer

Po-Hao Huang (2):
  rtw88: fix idle mode flow for hw scan
  rtw88: fix memory overrun and memory leak during hw_scan

 drivers/net/wireless/realtek/rtw88/fw.c       | 40 ++++++++++++++-----
 drivers/net/wireless/realtek/rtw88/mac80211.c |  5 ++-
 drivers/net/wireless/realtek/rtw88/main.c     | 16 +++++++-
 drivers/net/wireless/realtek/rtw88/main.h     |  4 +-
 4 files changed, 53 insertions(+), 12 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] rtw88: check for validity before using a pointer
  2022-01-21  7:08 [PATCH 0/3] rtw88: some fixes of hw_scan Ping-Ke Shih
@ 2022-01-21  7:08 ` Ping-Ke Shih
  2022-01-31 15:47   ` Kalle Valo
  2022-01-21  7:08 ` [PATCH 2/3] rtw88: fix idle mode flow for hw scan Ping-Ke Shih
  2022-01-21  7:08 ` [PATCH 3/3] rtw88: fix memory overrun and memory leak during hw_scan Ping-Ke Shih
  2 siblings, 1 reply; 5+ messages in thread
From: Ping-Ke Shih @ 2022-01-21  7:08 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: linux-wireless, usama.anjum, phhuang

From: Muhammad Usama Anjum <usama.anjum@collabora.com>

ieee80211_probereq_get() can return NULL. Pointer skb should be checked
for validty before use. If it is not valid, list of skbs needs to be
freed.

Fixes: 10d162b2ed39 ("rtw88: 8822c: add ieee80211_ops::hw_scan")
Signed-off-by: Muhammad Usama Anjum <usama.anjum@collabora.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/fw.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 2f7c036f90221..b56dc43229d28 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -1866,11 +1866,19 @@ static int rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev,
 					     req->ssids[i].ssid,
 					     req->ssids[i].ssid_len,
 					     req->ie_len);
+		if (!skb)
+			goto out;
 		rtw_append_probe_req_ie(rtwdev, skb, &list, rtwvif);
 		kfree_skb(skb);
 	}
 
 	return _rtw_hw_scan_update_probe_req(rtwdev, num, &list);
+
+out:
+	skb_queue_walk(&list, skb)
+		kfree_skb(skb);
+
+	return -ENOMEM;
 }
 
 static int rtw_add_chan_info(struct rtw_dev *rtwdev, struct rtw_chan_info *info,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] rtw88: fix idle mode flow for hw scan
  2022-01-21  7:08 [PATCH 0/3] rtw88: some fixes of hw_scan Ping-Ke Shih
  2022-01-21  7:08 ` [PATCH 1/3] rtw88: check for validity before using a pointer Ping-Ke Shih
@ 2022-01-21  7:08 ` Ping-Ke Shih
  2022-01-21  7:08 ` [PATCH 3/3] rtw88: fix memory overrun and memory leak during hw_scan Ping-Ke Shih
  2 siblings, 0 replies; 5+ messages in thread
From: Ping-Ke Shih @ 2022-01-21  7:08 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: linux-wireless, usama.anjum, phhuang

From: Po-Hao Huang <phhuang@realtek.com>

Upon hw scan completion, idle mode is not re-entered. This might
increase power consumption under no link mode. Fix this by adding the
re-enter flow. We need another work for this since enter_ips waits
for c2h_work to finish, which might lead to deadlock if caller is in
the same work.

Fixes: 10d162b2ed39 ("rtw88: 8822c: add ieee80211_ops::hw_scan")
Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/fw.c       |  2 +-
 drivers/net/wireless/realtek/rtw88/mac80211.c |  5 ++++-
 drivers/net/wireless/realtek/rtw88/main.c     | 16 +++++++++++++++-
 drivers/net/wireless/realtek/rtw88/main.h     |  4 +++-
 4 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index b56dc43229d28..a631042753eab 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -2030,7 +2030,7 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
 	rtwdev->hal.rcr |= BIT_CBSSID_BCN;
 	rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr);
 
-	rtw_core_scan_complete(rtwdev, vif);
+	rtw_core_scan_complete(rtwdev, vif, true);
 
 	ieee80211_wake_queues(rtwdev->hw);
 	ieee80211_scan_completed(rtwdev->hw, &info);
diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index ae7d97de5fdf4..647d2662955ba 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -72,6 +72,9 @@ static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
 	struct rtw_dev *rtwdev = hw->priv;
 	int ret = 0;
 
+	/* let previous ips work finish to ensure we don't leave ips twice */
+	cancel_work_sync(&rtwdev->ips_work);
+
 	mutex_lock(&rtwdev->mutex);
 
 	rtw_leave_lps_deep(rtwdev);
@@ -614,7 +617,7 @@ static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw,
 	struct rtw_dev *rtwdev = hw->priv;
 
 	mutex_lock(&rtwdev->mutex);
-	rtw_core_scan_complete(rtwdev, vif);
+	rtw_core_scan_complete(rtwdev, vif, false);
 	mutex_unlock(&rtwdev->mutex);
 }
 
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 38252113c4a87..39c223a2e3e2d 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -272,6 +272,15 @@ static void rtw_c2h_work(struct work_struct *work)
 	}
 }
 
+static void rtw_ips_work(struct work_struct *work)
+{
+	struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, ips_work);
+
+	mutex_lock(&rtwdev->mutex);
+	rtw_enter_ips(rtwdev);
+	mutex_unlock(&rtwdev->mutex);
+}
+
 static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
 {
 	unsigned long mac_id;
@@ -1339,7 +1348,8 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
 	set_bit(RTW_FLAG_SCANNING, rtwdev->flags);
 }
 
-void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
+			    bool hw_scan)
 {
 	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
 	u32 config = 0;
@@ -1354,6 +1364,9 @@ void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif)
 	rtw_vif_port_config(rtwdev, rtwvif, config);
 
 	rtw_coex_scan_notify(rtwdev, COEX_SCAN_FINISH);
+
+	if (rtwvif->net_type == RTW_NET_NO_LINK && hw_scan)
+		ieee80211_queue_work(rtwdev->hw, &rtwdev->ips_work);
 }
 
 int rtw_core_start(struct rtw_dev *rtwdev)
@@ -1919,6 +1932,7 @@ int rtw_core_init(struct rtw_dev *rtwdev)
 	INIT_DELAYED_WORK(&coex->wl_ccklock_work, rtw_coex_wl_ccklock_work);
 	INIT_WORK(&rtwdev->tx_work, rtw_tx_work);
 	INIT_WORK(&rtwdev->c2h_work, rtw_c2h_work);
+	INIT_WORK(&rtwdev->ips_work, rtw_ips_work);
 	INIT_WORK(&rtwdev->fw_recovery_work, rtw_fw_recovery_work);
 	INIT_WORK(&rtwdev->ba_work, rtw_txq_ba_work);
 	skb_queue_head_init(&rtwdev->c2h_queue);
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index dc1cd9bd4b8a3..36e1e408933db 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1960,6 +1960,7 @@ struct rtw_dev {
 	/* c2h cmd queue & handler work */
 	struct sk_buff_head c2h_queue;
 	struct work_struct c2h_work;
+	struct work_struct ips_work;
 	struct work_struct fw_recovery_work;
 
 	/* used to protect txqs list */
@@ -2101,7 +2102,8 @@ void rtw_tx_report_purge_timer(struct timer_list *t);
 void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si);
 void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
 			 const u8 *mac_addr, bool hw_scan);
-void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif);
+void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
+			    bool hw_scan);
 int rtw_core_start(struct rtw_dev *rtwdev);
 void rtw_core_stop(struct rtw_dev *rtwdev);
 int rtw_chip_info_setup(struct rtw_dev *rtwdev);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] rtw88: fix memory overrun and memory leak during hw_scan
  2022-01-21  7:08 [PATCH 0/3] rtw88: some fixes of hw_scan Ping-Ke Shih
  2022-01-21  7:08 ` [PATCH 1/3] rtw88: check for validity before using a pointer Ping-Ke Shih
  2022-01-21  7:08 ` [PATCH 2/3] rtw88: fix idle mode flow for hw scan Ping-Ke Shih
@ 2022-01-21  7:08 ` Ping-Ke Shih
  2 siblings, 0 replies; 5+ messages in thread
From: Ping-Ke Shih @ 2022-01-21  7:08 UTC (permalink / raw)
  To: tony0620emma, kvalo; +Cc: linux-wireless, usama.anjum, phhuang

From: Po-Hao Huang <phhuang@realtek.com>

Previously we allocated less memory than actual required, overwrite
to the buffer causes the mm module to complaint and raise access
violation faults. Along with potential memory leaks when returned
early. Fix these by passing the correct size and proper deinit flow.

Fixes: 10d162b2ed39 ("rtw88: 8822c: add ieee80211_ops::hw_scan")
Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/fw.c | 34 +++++++++++++++++--------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index a631042753eab..ce9535cce7232 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -1784,9 +1784,9 @@ void rtw_fw_scan_notify(struct rtw_dev *rtwdev, bool start)
 	rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 }
 
-static void rtw_append_probe_req_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
-				    struct sk_buff_head *list,
-				    struct rtw_vif *rtwvif)
+static int rtw_append_probe_req_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
+				   struct sk_buff_head *list, u8 *bands,
+				   struct rtw_vif *rtwvif)
 {
 	struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
 	struct rtw_chip_info *chip = rtwdev->chip;
@@ -1797,19 +1797,24 @@ static void rtw_append_probe_req_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
 		if (!(BIT(idx) & chip->band))
 			continue;
 		new = skb_copy(skb, GFP_KERNEL);
+		if (!new)
+			return -ENOMEM;
 		skb_put_data(new, ies->ies[idx], ies->len[idx]);
 		skb_put_data(new, ies->common_ies, ies->common_ie_len);
 		skb_queue_tail(list, new);
+		(*bands)++;
 	}
+
+	return 0;
 }
 
-static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_ssids,
+static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_probes,
 					 struct sk_buff_head *probe_req_list)
 {
 	struct rtw_chip_info *chip = rtwdev->chip;
 	struct sk_buff *skb, *tmp;
 	u8 page_offset = 1, *buf, page_size = chip->page_size;
-	u8 pages = page_offset + num_ssids * RTW_PROBE_PG_CNT;
+	u8 pages = page_offset + num_probes * RTW_PROBE_PG_CNT;
 	u16 pg_addr = rtwdev->fifo.rsvd_h2c_info_addr, loc;
 	u16 buf_offset = page_size * page_offset;
 	u8 tx_desc_sz = chip->tx_pkt_desc_sz;
@@ -1848,6 +1853,8 @@ static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_ssids,
 	rtwdev->scan_info.probe_pg_size = page_offset;
 out:
 	kfree(buf);
+	skb_queue_walk(probe_req_list, skb)
+		kfree_skb(skb);
 
 	return ret;
 }
@@ -1858,7 +1865,8 @@ static int rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev,
 	struct cfg80211_scan_request *req = rtwvif->scan_req;
 	struct sk_buff_head list;
 	struct sk_buff *skb;
-	u8 num = req->n_ssids, i;
+	u8 num = req->n_ssids, i, bands = 0;
+	int ret;
 
 	skb_queue_head_init(&list);
 	for (i = 0; i < num; i++) {
@@ -1866,19 +1874,25 @@ static int rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev,
 					     req->ssids[i].ssid,
 					     req->ssids[i].ssid_len,
 					     req->ie_len);
-		if (!skb)
+		if (!skb) {
+			ret = -ENOMEM;
 			goto out;
-		rtw_append_probe_req_ie(rtwdev, skb, &list, rtwvif);
+		}
+		ret = rtw_append_probe_req_ie(rtwdev, skb, &list, &bands,
+					      rtwvif);
+		if (ret)
+			goto out;
+
 		kfree_skb(skb);
 	}
 
-	return _rtw_hw_scan_update_probe_req(rtwdev, num, &list);
+	return _rtw_hw_scan_update_probe_req(rtwdev, num * bands, &list);
 
 out:
 	skb_queue_walk(&list, skb)
 		kfree_skb(skb);
 
-	return -ENOMEM;
+	return ret;
 }
 
 static int rtw_add_chan_info(struct rtw_dev *rtwdev, struct rtw_chan_info *info,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/3] rtw88: check for validity before using a pointer
  2022-01-21  7:08 ` [PATCH 1/3] rtw88: check for validity before using a pointer Ping-Ke Shih
@ 2022-01-31 15:47   ` Kalle Valo
  0 siblings, 0 replies; 5+ messages in thread
From: Kalle Valo @ 2022-01-31 15:47 UTC (permalink / raw)
  To: Ping-Ke Shih; +Cc: tony0620emma, linux-wireless, usama.anjum, phhuang

Ping-Ke Shih <pkshih@realtek.com> wrote:

> From: Muhammad Usama Anjum <usama.anjum@collabora.com>
> 
> ieee80211_probereq_get() can return NULL. Pointer skb should be checked
> for validty before use. If it is not valid, list of skbs needs to be
> freed.
> 
> Fixes: 10d162b2ed39 ("rtw88: 8822c: add ieee80211_ops::hw_scan")
> Signed-off-by: Muhammad Usama Anjum <usama.anjum@collabora.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>

3 patches applied to wireless-next.git, thanks.

a12f809968db rtw88: check for validity before using a pointer
c17f27167b4c rtw88: fix idle mode flow for hw scan
d95984b5580d rtw88: fix memory overrun and memory leak during hw_scan

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/20220121070813.9656-2-pkshih@realtek.com/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-01-31 15:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-21  7:08 [PATCH 0/3] rtw88: some fixes of hw_scan Ping-Ke Shih
2022-01-21  7:08 ` [PATCH 1/3] rtw88: check for validity before using a pointer Ping-Ke Shih
2022-01-31 15:47   ` Kalle Valo
2022-01-21  7:08 ` [PATCH 2/3] rtw88: fix idle mode flow for hw scan Ping-Ke Shih
2022-01-21  7:08 ` [PATCH 3/3] rtw88: fix memory overrun and memory leak during hw_scan Ping-Ke Shih

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).