From: Ben Greear Date: Wed, 20 Feb 2013 17:41:09 +0000 (-0800) Subject: mac80211: Fix crash due to un-canceled work-items X-Git-Tag: v3.12-rc1~1033^2~11^2^2~1^2~19 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=499218595a2e8296b7492af32fcca141b7b8184a;p=kernel%2Fkernel-generic.git mac80211: Fix crash due to un-canceled work-items Some mlme work structs are not cancelled on disassociation nor interface deletion, which leads to them running after the memory has been freed There is not a clean way to cancel these in the disassociation logic because they must be canceled outside of the ifmgd->mtx lock, so just cancel them in mgd_stop logic that tears down the station. This fixes the crashes we see in 3.7.9+. The crash stack trace itself isn't so helpful, but this warning gives more useful info: WARNING: at /home/greearb/git/linux-3.7.dev.y/lib/debugobjects.c:261 debug_print_object+0x7c/0x8d() ODEBUG: free active (active state 0) object type: work_struct hint: ieee80211_sta_monitor_work+0x0/0x14 [mac80211] Modules linked in: [...] Pid: 14743, comm: iw Tainted: G C O 3.7.9+ #11 Call Trace: [] warn_slowpath_common+0x80/0x98 [] warn_slowpath_fmt+0x41/0x43 [] debug_print_object+0x7c/0x8d [] debug_check_no_obj_freed+0x95/0x1c3 [] slab_free_hook+0x70/0x79 [] kfree+0x62/0xb7 [] netdev_release+0x39/0x3e [] device_release+0x52/0x8a [] kobject_release+0x121/0x158 [] kobject_put+0x4c/0x50 [] netdev_run_todo+0x25c/0x27e Cc: stable@vger.kernel.org Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 6044c6d..b756d29 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -4319,6 +4319,17 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + /* + * Make sure some work items will not run after this, + * they will not do anything but might not have been + * cancelled when disconnecting. + */ + cancel_work_sync(&ifmgd->monitor_work); + cancel_work_sync(&ifmgd->beacon_connection_loss_work); + cancel_work_sync(&ifmgd->request_smps_work); + cancel_work_sync(&ifmgd->csa_connection_drop_work); + cancel_work_sync(&ifmgd->chswitch_work); + mutex_lock(&ifmgd->mtx); if (ifmgd->assoc_data) ieee80211_destroy_assoc_data(sdata, false);