Skip to content

Commit 1395f8d

Browse files
committed
Merge tag 'mac80211-for-net-2020-11-13' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says: ==================== A handful of fixes: * a use-after-free fix in rfkill * a memory leak fix in the mac80211 TX status path * some rate scaling fixes * a fix for the often-reported (by syzbot) sleeping in atomic issue with mac80211's station removal * tag 'mac80211-for-net-2020-11-13' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211: mac80211: free sta in sta_info_insert_finish() on errors mac80211: minstrel: fix tx status processing corner case mac80211: minstrel: remove deferred sampling code mac80211: fix memory leak on filtered powersave frames rfkill: Fix use-after-free in rfkill_resume() ==================== Link: https://lore.kernel.org/r/20201113093421.24025-1-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 4ee18c1 + 7bc40ae commit 1395f8d

File tree

5 files changed

+20
-43
lines changed

5 files changed

+20
-43
lines changed

net/mac80211/rc80211_minstrel.c

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
274274
success = !!(info->flags & IEEE80211_TX_STAT_ACK);
275275

276276
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
277-
if (ar[i].idx < 0)
277+
if (ar[i].idx < 0 || !ar[i].count)
278278
break;
279279

280280
ndx = rix_to_ndx(mi, ar[i].idx);
@@ -287,12 +287,6 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
287287
mi->r[ndx].stats.success += success;
288288
}
289289

290-
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0))
291-
mi->sample_packets++;
292-
293-
if (mi->sample_deferred > 0)
294-
mi->sample_deferred--;
295-
296290
if (time_after(jiffies, mi->last_stats_update +
297291
mp->update_interval / (mp->new_avg ? 2 : 1)))
298292
minstrel_update_stats(mp, mi);
@@ -367,7 +361,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
367361
return;
368362

369363
delta = (mi->total_packets * sampling_ratio / 100) -
370-
(mi->sample_packets + mi->sample_deferred / 2);
364+
mi->sample_packets;
371365

372366
/* delta < 0: no sampling required */
373367
prev_sample = mi->prev_sample;
@@ -376,7 +370,6 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
376370
return;
377371

378372
if (mi->total_packets >= 10000) {
379-
mi->sample_deferred = 0;
380373
mi->sample_packets = 0;
381374
mi->total_packets = 0;
382375
} else if (delta > mi->n_rates * 2) {
@@ -401,19 +394,8 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
401394
* rate sampling method should be used.
402395
* Respect such rates that are not sampled for 20 interations.
403396
*/
404-
if (mrr_capable &&
405-
msr->perfect_tx_time > mr->perfect_tx_time &&
406-
msr->stats.sample_skipped < 20) {
407-
/* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark
408-
* packets that have the sampling rate deferred to the
409-
* second MRR stage. Increase the sample counter only
410-
* if the deferred sample rate was actually used.
411-
* Use the sample_deferred counter to make sure that
412-
* the sampling is not done in large bursts */
413-
info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
414-
rate++;
415-
mi->sample_deferred++;
416-
} else {
397+
if (msr->perfect_tx_time < mr->perfect_tx_time ||
398+
msr->stats.sample_skipped >= 20) {
417399
if (!msr->sample_limit)
418400
return;
419401

@@ -433,6 +415,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
433415

434416
rate->idx = mi->r[ndx].rix;
435417
rate->count = minstrel_get_retry_count(&mi->r[ndx], info);
418+
info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
436419
}
437420

438421

net/mac80211/rc80211_minstrel.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ struct minstrel_sta_info {
126126
u8 max_prob_rate;
127127
unsigned int total_packets;
128128
unsigned int sample_packets;
129-
int sample_deferred;
130129

131130
unsigned int sample_row;
132131
unsigned int sample_column;

net/mac80211/sta_info.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
705705
out_drop_sta:
706706
local->num_sta--;
707707
synchronize_net();
708-
__cleanup_single_sta(sta);
708+
cleanup_single_sta(sta);
709709
out_err:
710710
mutex_unlock(&local->sta_mtx);
711711
kfree(sinfo);
@@ -724,19 +724,13 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
724724

725725
err = sta_info_insert_check(sta);
726726
if (err) {
727+
sta_info_free(local, sta);
727728
mutex_unlock(&local->sta_mtx);
728729
rcu_read_lock();
729-
goto out_free;
730+
return err;
730731
}
731732

732-
err = sta_info_insert_finish(sta);
733-
if (err)
734-
goto out_free;
735-
736-
return 0;
737-
out_free:
738-
sta_info_free(local, sta);
739-
return err;
733+
return sta_info_insert_finish(sta);
740734
}
741735

742736
int sta_info_insert(struct sta_info *sta)

net/mac80211/status.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
4949
int ac;
5050

5151
if (info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
52-
IEEE80211_TX_CTL_AMPDU)) {
52+
IEEE80211_TX_CTL_AMPDU |
53+
IEEE80211_TX_CTL_HW_80211_ENCAP)) {
5354
ieee80211_free_txskb(&local->hw, skb);
5455
return;
5556
}
@@ -915,15 +916,6 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
915916
ieee80211_mpsp_trigger_process(
916917
ieee80211_get_qos_ctl(hdr), sta, true, acked);
917918

918-
if (!acked && test_sta_flag(sta, WLAN_STA_PS_STA)) {
919-
/*
920-
* The STA is in power save mode, so assume
921-
* that this TX packet failed because of that.
922-
*/
923-
ieee80211_handle_filtered_frame(local, sta, skb);
924-
return;
925-
}
926-
927919
if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL) &&
928920
(ieee80211_is_data(hdr->frame_control)) &&
929921
(rates_idx != -1))
@@ -1150,6 +1142,12 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
11501142
-info->status.ack_signal);
11511143
}
11521144
} else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
1145+
/*
1146+
* The STA is in power save mode, so assume
1147+
* that this TX packet failed because of that.
1148+
*/
1149+
if (skb)
1150+
ieee80211_handle_filtered_frame(local, sta, skb);
11531151
return;
11541152
} else if (noack_success) {
11551153
/* nothing to do here, do not account as lost */

net/rfkill/core.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,9 @@ static int rfkill_resume(struct device *dev)
876876

877877
rfkill->suspended = false;
878878

879+
if (!rfkill->registered)
880+
return 0;
881+
879882
if (!rfkill->persistent) {
880883
cur = !!(rfkill->state & RFKILL_BLOCK_SW);
881884
rfkill_set_block(rfkill, cur);

0 commit comments

Comments
 (0)