aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2010-10-02 07:17:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-05 13:35:21 -0400
commit85416a4fa193754ef36e12b20bb02fe661cb7f17 (patch)
tree45228e888bd76a5f1251c55ea28377ddedfe2914 /net/mac80211/cfg.c
parent5a254ffe3ffdfa84fe076009bd8e88da412180d2 (diff)
mac80211: fix rx monitor filter refcounters
This patch fixes an refcounting bug. Previously it was possible to corrupt the per-device recv. filter and monitor management counters when: iw dev wlanX set monitor [new flags] was issued on an active monitor interface. Acked-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c981604b71e..9e63fc28f85 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -68,8 +68,36 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
68 params && params->use_4addr >= 0) 68 params && params->use_4addr >= 0)
69 sdata->u.mgd.use_4addr = params->use_4addr; 69 sdata->u.mgd.use_4addr = params->use_4addr;
70 70
71 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) 71 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
72 sdata->u.mntr_flags = *flags; 72 struct ieee80211_local *local = sdata->local;
73
74 if (ieee80211_sdata_running(sdata)) {
75 /*
76 * Prohibit MONITOR_FLAG_COOK_FRAMES to be
77 * changed while the interface is up.
78 * Else we would need to add a lot of cruft
79 * to update everything:
80 * cooked_mntrs, monitor and all fif_* counters
81 * reconfigure hardware
82 */
83 if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
84 (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
85 return -EBUSY;
86
87 ieee80211_adjust_monitor_flags(sdata, -1);
88 sdata->u.mntr_flags = *flags;
89 ieee80211_adjust_monitor_flags(sdata, 1);
90
91 ieee80211_configure_filter(local);
92 } else {
93 /*
94 * Because the interface is down, ieee80211_do_stop
95 * and ieee80211_do_open take care of "everything"
96 * mentioned in the comment above.
97 */
98 sdata->u.mntr_flags = *flags;
99 }
100 }
73 101
74 return 0; 102 return 0;
75} 103}