Message ID | 1463332756-31423-1-git-send-email-me@bobcopeland.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Johannes Berg |
Headers | show |
On Sun, 2016-05-15 at 13:19 -0400, Bob Copeland wrote: > Currently, the mesh paths associated with a nexthop station are > cleaned > up in the following code path: > > __sta_info_destroy_part1 > synchronize_net() > __sta_info_destroy_part2 > -> cleanup_single_sta > -> mesh_sta_cleanup > -> mesh_plink_deactivate > -> mesh_path_flush_by_nexthop > > However, there are a couple of problems here: > > 1) the paths aren't flushed at all if the MPM is running in userspace > (e.g. when using wpa_supplicant or authsae) > > 2) there is no synchronize_rcu between removing the path and readers > accessing the nexthop, which means the following race is possible: > > CPU0 CPU1 > ~~~~ ~~~~ > sta_info_destroy_part1() > synchronize_net() > rcu_read_lock() > mesh_nexthop_resolve() > mpath = mesh_path_lookup() > [...] -> mesh_path_flush_by_nexthop() > sta = rcu_dereference( > mpath->next_hop) > kfree(sta) > access sta <-- CRASH > > Fix both of these by unconditionally flushing paths before destroying > the sta, and by adding a synchronize_net() after path flush to ensure > no active readers can still dereference the sta. > [...] Applied, thanks for the fix and the detailed description! johannes -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 4c6404e1ad6e..21b1fdf5d01d 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -161,6 +161,10 @@ void mesh_sta_cleanup(struct sta_info *sta) del_timer_sync(&sta->mesh->plink_timer); } + /* make sure no readers can access nexthop sta from here on */ + mesh_path_flush_by_nexthop(sta); + synchronize_net(); + if (changed) ieee80211_mbss_info_change_notify(sdata, changed); }