1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 23 Feb 2023 00:10:25 +0100
Subject: wifi: mt76: do not run mt76_unregister_device() on unregistered hw
Origin: https://patchwork.kernel.org/project/linux-wireless/patch/be3457d82f4e44bb71a22b2b5db27b644a37b1e1.1677107277.git.lorenzo@kernel.org/
Bug-Debian: https://bugs.debian.org/1029116
Trying to probe a mt7921e pci card without firmware results in a
successful probe where ieee80211_register_hw hasn't been called. When
removing the driver, ieee802111_unregister_hw is called unconditionally
leading to a kernel NULL pointer dereference.
Fix the issue running mt76_unregister_device routine just for registered
hw.
Link: https://bugs.debian.org/1029116
Link: https://bugs.kali.org/view.php?id=8140
Reported-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
Fixes: 1c71e03afe4b ("mt76: mt7921: move mt7921_init_hw in a dedicated work")
Tested-by: Helmut Grohne <helmut@freexian.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Currently queued for review for the v6.3 release cycle, backported in
advance to prevent users from getting stuck in the installer.
Signed-off-by: Cyril Brulebois <kibi@debian.org>
---
drivers/net/wireless/mediatek/mt76/mac80211.c | 8 ++++++++
drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
2 files changed, 9 insertions(+)
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -522,6 +522,7 @@ int mt76_register_phy(struct mt76_phy *p
if (ret)
return ret;
+ set_bit(MT76_STATE_REGISTERED, &phy->state);
phy->dev->phys[phy->band_idx] = phy;
return 0;
@@ -532,6 +533,9 @@ void mt76_unregister_phy(struct mt76_phy
{
struct mt76_dev *dev = phy->dev;
+ if (!test_bit(MT76_STATE_REGISTERED, &phy->state))
+ return;
+
mt76_tx_status_check(dev, true);
ieee80211_unregister_hw(phy->hw);
dev->phys[phy->band_idx] = NULL;
@@ -654,6 +658,7 @@ int mt76_register_device(struct mt76_dev
return ret;
WARN_ON(mt76_worker_setup(hw, &dev->tx_worker, NULL, "tx"));
+ set_bit(MT76_STATE_REGISTERED, &phy->state);
sched_set_fifo_low(dev->tx_worker.task);
return 0;
@@ -664,6 +669,9 @@ void mt76_unregister_device(struct mt76_
{
struct ieee80211_hw *hw = dev->hw;
+ if (!test_bit(MT76_STATE_REGISTERED, &dev->phy.state))
+ return;
+
if (IS_ENABLED(CONFIG_MT76_LEDS))
mt76_led_cleanup(dev);
mt76_tx_status_check(dev, true);
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -388,6 +388,7 @@ struct mt76_tx_cb {
enum {
MT76_STATE_INITIALIZED,
+ MT76_STATE_REGISTERED,
MT76_STATE_RUNNING,
MT76_STATE_MCU_RUNNING,
MT76_SCANNING,
|