Search Linux Wireless

Re: Memory leak in cfg80211

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Johannes,

You got it right. I got two tracebacks as follows:

[ 22.147978] cfg80211: wiphy->regd changed at line 1459: old (null), new: ffff8800b1e25a80
[   22.147982] Pid: 292, comm: kworker/1:1 Not tainted 3.8.0-rc6-wl+ #96
[   22.147985] Call Trace:
[   22.148032]  [<ffffffffa03c6623>] reg_todo+0x403/0x5e0 [cfg80211]
[   22.148088]  [<ffffffff81063cdd>] process_one_work+0x19d/0x6f0
[   22.148098]  [<ffffffff81063c70>] ? process_one_work+0x130/0x6f0
[   22.148103]  [<ffffffff810ba840>] ? cgroup_path+0x170/0x170
[   22.148120]  [<ffffffffa03c6220>] ? regdom_changes+0x50/0x50 [cfg80211]
[   22.148128]  [<ffffffff81064605>] worker_thread+0x155/0x400
[   22.148134]  [<ffffffff810a568d>] ? trace_hardirqs_on+0xd/0x10
[   22.148139]  [<ffffffff810644b0>] ? rescuer_thread+0x240/0x240
[   22.148144]  [<ffffffff81069b56>] kthread+0xd6/0xe0
[   22.148150]  [<ffffffff8145acab>] ? _raw_spin_unlock_irq+0x2b/0x50
[   22.148155]  [<ffffffff81069a80>] ? __init_kthread_worker+0x70/0x70
[   22.148160]  [<ffffffff8145ba7c>] ret_from_fork+0x7c/0xb0
[   22.148164]  [<ffffffff81069a80>] ? __init_kthread_worker+0x70/0x70
[   22.148169] cfg80211: Calling CRDA for country: CN


[ 22.161223] cfg80211: request_wiphy->regd changed at line 2199: old ffff8800b1e25a80, new: ffff8800b61c66c0
[   22.161230] Pid: 2377, comm: crda Not tainted 3.8.0-rc6-wl+ #96
[   22.161233] Call Trace:
[   22.161275]  [<ffffffffa03c76fc>] set_regdom+0x6dc/0x750 [cfg80211]
[   22.161293]  [<ffffffffa03d1f56>] nl80211_set_reg+0x236/0x2a0 [cfg80211]
[   22.161302]  [<ffffffff813d2e24>] genl_rcv_msg+0x274/0x2b0
[   22.161306]  [<ffffffff813d2bb0>] ? genl_rcv+0x30/0x30
[   22.161311]  [<ffffffff813d20b9>] netlink_rcv_skb+0xa9/0xc0
[   22.161315]  [<ffffffff813d2ba0>] genl_rcv+0x20/0x30
[   22.161319]  [<ffffffff813d1a0b>] netlink_unicast+0x19b/0x220
[   22.161324]  [<ffffffff813d1e76>] netlink_sendmsg+0x336/0x3b0
[   22.161329]  [<ffffffff81390b17>] sock_sendmsg+0x87/0xa0
[   22.161335]  [<ffffffff81127aa7>] ? might_fault+0x57/0xb0
[   22.161340]  [<ffffffff81390fcc>] __sys_sendmsg+0x37c/0x390
[   22.161345]  [<ffffffff8106f9be>] ? up_read+0x1e/0x40
[   22.161350]  [<ffffffff81033b3c>] ? __do_page_fault+0x1fc/0x500
[   22.161356]  [<ffffffff8116f1aa>] ? fget_light+0x3da/0x4d0
[   22.161359]  [<ffffffff81393f08>] ? sys_getsockname+0xb8/0xc0
[   22.161363]  [<ffffffff813944e4>] sys_sendmsg+0x44/0x80
[   22.161368]  [<ffffffff8145bb29>] system_call_fastpath+0x16/0x1b

The second one replaced a non-NULL pointer, and kmemleak confirms that it is the leaked block.

larrylap:~ # cat /sys/kernel/debug/kmemleak
unreferenced object 0xffff8800b1e25a80 (size 192):
  comm "kworker/1:1", pid 292, jiffies 4294897832 (age 3645.856s)
  hex dump (first 32 bytes):
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    06 00 00 00 55 53 00 00 d0 a6 24 00 40 b8 25 00  ....US....$.@.%.
  backtrace:
    [<ffffffff81444cf1>] kmemleak_alloc+0x21/0x50
    [<ffffffff81147770>] __kmalloc+0x130/0x2c0
    [<ffffffffa03c5473>] reg_copy_regd+0x23/0xa0 [cfg80211]
    [<ffffffffa03c65f2>] reg_todo+0x3d2/0x5e0 [cfg80211]
    [<ffffffff81063cdd>] process_one_work+0x19d/0x6f0
    [<ffffffff81064605>] worker_thread+0x155/0x400
    [<ffffffff81069b56>] kthread+0xd6/0xe0
    [<ffffffff8145ba7c>] ret_from_fork+0x7c/0xb0
    [<ffffffffffffffff>] 0xffffffffffffffff
larrylap:~ #

This leak seems to occur because I am loading cfg80211 with the regdom set to "US"; however, the driver is forcing "CN". That is my penalty for buying the adapter on Ebay; however, I think my setting should override that of the driver, which might be a separate bug. I'm OK as long as there are no FCC inspectors in my neighborhood to see that I am sending out probes on channels 12 and 13.

I am only vaguely familiar with the rcu routines. Is it sufficient to do the simple kfree() before the rcu_assign_pointer() call, or is it necessary to make an rcu_lock() call as well? If a simple kfree() is all that is needed, then the following patch should be OK. If is is, I'll do some testing and do a proper submission later:

Index: wireless-testing-new/net/wireless/reg.c
===================================================================
--- wireless-testing-new.orig/net/wireless/reg.c
+++ wireless-testing-new/net/wireless/reg.c
@@ -2189,10 +2189,12 @@ static int __set_regdom(const struct iee
                 * However if a driver requested this specific regulatory
                 * domain we keep it for its private use
                 */
-               if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER)
+               if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER) {
+                       kfree(request_wiphy->regd);
                        rcu_assign_pointer(request_wiphy->regd, rd);
-               else
+               } else {
                        kfree(rd);
+               }

                rd = NULL;

Larry

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux