diff mbox series

[v2] wifi: mac80211: fix memory leak in ieee80211_register_hw()

Message ID 20221202043838.2324539-1-shaozhengchao@huawei.com
State New
Headers show
Series [v2] wifi: mac80211: fix memory leak in ieee80211_register_hw() | expand

Commit Message

shaozhengchao Dec. 2, 2022, 4:38 a.m. UTC
When ieee80211_init_rate_ctrl_alg() failed in ieee80211_register_hw(),
it doesn't release local->fq. The memory leakage information is as
follows:
unreferenced object 0xffff888109cad400 (size 512):
  comm "insmod", pid 15145, jiffies 4295005736 (age 3670.100s)
  hex dump (first 32 bytes):
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<00000000d1eb4a9f>] __kmalloc+0x3e/0xb0
    [<00000000befc3e34>] ieee80211_txq_setup_flows+0x1fe/0xa10
    [<00000000b13f1457>] ieee80211_register_hw+0x1b64/0x3950
    [<00000000ba9f4e99>] 0xffffffffa02214db
    [<00000000833435c0>] 0xffffffffa024048d
    [<00000000a4ddd6ef>] do_one_initcall+0x10f/0x630
    [<0000000068f29e16>] do_init_module+0x19f/0x5e0
    [<00000000f52609b6>] load_module+0x64b7/0x6eb0
    [<00000000b628a5b3>] __do_sys_finit_module+0x140/0x200
    [<00000000c7f35d15>] do_syscall_64+0x35/0x80
    [<0000000044d8d0fd>] entry_SYSCALL_64_after_hwframe+0x46/0xb0

Fixes: a50e5fb8db83 ("mac80211: fix a kernel panic when TXing after TXQ teardown")
Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
---
v2: Don't remove flows clear action in ieee80211_remove_interfaces()
---
 net/mac80211/main.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Johannes Berg Jan. 18, 2023, 9:45 a.m. UTC | #1
On Fri, 2022-12-02 at 12:38 +0800, Zhengchao Shao wrote:
> 
> --- a/net/mac80211/main.c
> +++ b/net/mac80211/main.c
> @@ -1326,6 +1326,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
>  					      hw->rate_control_algorithm);
>  	rtnl_unlock();
>  	if (result < 0) {
> +		ieee80211_txq_teardown_flows(local);
>  		wiphy_debug(local->hw.wiphy,
>  			    "Failed to initialize rate control algorithm\n");
>  		goto fail_rate;
> @@ -1364,6 +1365,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
>  
>  		sband = kmemdup(sband, sizeof(*sband), GFP_KERNEL);
>  		if (!sband) {
> +			ieee80211_txq_teardown_flows(local);
>  			result = -ENOMEM;
>  			goto fail_rate;
>  		}

I don't understand - we have a fail_rate label here where we free
everything.

What if we get to fail_wiphy_register, don't we leak it in the same way?

johannes
shaozhengchao Jan. 29, 2023, 6:28 a.m. UTC | #2
On 2023/1/18 17:45, Johannes Berg wrote:
> On Fri, 2022-12-02 at 12:38 +0800, Zhengchao Shao wrote:
>>
>> --- a/net/mac80211/main.c
>> +++ b/net/mac80211/main.c
>> @@ -1326,6 +1326,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
>>   					      hw->rate_control_algorithm);
>>   	rtnl_unlock();
>>   	if (result < 0) {
>> +		ieee80211_txq_teardown_flows(local);
>>   		wiphy_debug(local->hw.wiphy,
>>   			    "Failed to initialize rate control algorithm\n");
>>   		goto fail_rate;
>> @@ -1364,6 +1365,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
>>   
>>   		sband = kmemdup(sband, sizeof(*sband), GFP_KERNEL);
>>   		if (!sband) {
>> +			ieee80211_txq_teardown_flows(local);
>>   			result = -ENOMEM;
>>   			goto fail_rate;
>>   		}
> 
> I don't understand - we have a fail_rate label here where we free
> everything.
> 
> What if we get to fail_wiphy_register, don't we leak it in the same way?
> 
> johannes

Hi johannes:
	Thank you for your review. Sorry it took so long to reply. The
fail_rate label does not release the resources applied for in the
ieee80211_txq_setup_flows().  Or maybe I missed something?
	The fail_wiphy_register label will call
ieee80211_remove_interfaces()->ieee80211_txq_teardown_flows() to release
resources. So it is OK.

Zhengchao Shao
Johannes Berg Feb. 14, 2023, 9:58 a.m. UTC | #3
On Sun, 2023-01-29 at 14:28 +0800, shaozhengchao wrote:
> 
> On 2023/1/18 17:45, Johannes Berg wrote:
> > On Fri, 2022-12-02 at 12:38 +0800, Zhengchao Shao wrote:
> > > 
> > > --- a/net/mac80211/main.c
> > > +++ b/net/mac80211/main.c
> > > @@ -1326,6 +1326,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
> > >   					      hw->rate_control_algorithm);
> > >   	rtnl_unlock();
> > >   	if (result < 0) {
> > > +		ieee80211_txq_teardown_flows(local);
> > >   		wiphy_debug(local->hw.wiphy,
> > >   			    "Failed to initialize rate control algorithm\n");
> > >   		goto fail_rate;
> > > @@ -1364,6 +1365,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
> > >   
> > >   		sband = kmemdup(sband, sizeof(*sband), GFP_KERNEL);
> > >   		if (!sband) {
> > > +			ieee80211_txq_teardown_flows(local);
> > >   			result = -ENOMEM;
> > >   			goto fail_rate;
> > >   		}
> > 
> > I don't understand - we have a fail_rate label here where we free
> > everything.
> > 
> > What if we get to fail_wiphy_register, don't we leak it in the same way?
> > 
> > johannes


> 	Thank you for your review. Sorry it took so long to reply. The
> fail_rate label does not release the resources applied for in the
> ieee80211_txq_setup_flows().  Or maybe I missed something?

That's my point though - if we "goto fail_ifa" or "goto
fail_wiphy_register", we have the same bug, no?

So shouldn't the patch simply be this:

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 846528850612..a42d1f0ef7a5 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1442,6 +1442,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 	ieee80211_remove_interfaces(local);
 	rtnl_unlock();
  fail_rate:
+	ieee80211_txq_teardown_flows(local);
  fail_flows:
 	ieee80211_led_exit(local);
 	destroy_workqueue(local->workqueue);


johannes
diff mbox series

Patch

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 02b5abc7326b..18edf0591c2e 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1326,6 +1326,7 @@  int ieee80211_register_hw(struct ieee80211_hw *hw)
 					      hw->rate_control_algorithm);
 	rtnl_unlock();
 	if (result < 0) {
+		ieee80211_txq_teardown_flows(local);
 		wiphy_debug(local->hw.wiphy,
 			    "Failed to initialize rate control algorithm\n");
 		goto fail_rate;
@@ -1364,6 +1365,7 @@  int ieee80211_register_hw(struct ieee80211_hw *hw)
 
 		sband = kmemdup(sband, sizeof(*sband), GFP_KERNEL);
 		if (!sband) {
+			ieee80211_txq_teardown_flows(local);
 			result = -ENOMEM;
 			goto fail_rate;
 		}