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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAl+uSaYACgkQB8qZga/f l8Q83A/8DaRC1M1nuhnPeMXJd73qxPk58+WqmBJU8sQEGtyCHyQZ6EdHUgW/V4ww Yh4vYBOoiWGG6JC0N0G02O4SxGmk3hZyTdxJ8WxnsM7pJ4yzWufduJrYvnx59mbh muw+WgEYLdyWYyzn81/rmfvQKfeFiic4pwSBuru2o0Vhb2bNYeUpYIMmdHkzlEyV BEwdVGCSvKWuxXdGCbplAJ79MbN6jP03y1+u7ZLYz7P+OvZZVQqUFouNuHUfrLUs nS8sgRToFTDt1Hu9GagRvbvqpwXGFgH+4LpMwLLa4mFjPcCC2UPewbiSIk7EU4tU wCr9pRlQXmcD+yVuWvwEQJvHQgkzm/Krx517QteXYB/GLmNC0A43kyQK+CEDlk56 Fj0hk3UmXmek2EBEI/jLURlsJr7QMWqRRXXVK2VIvEButP+iWmPPyZ01Tkfjz5IN jHl8ahiSqX3kcCZLldlvkmtwqKKtgE4coQnPVOJJRBKYX5YpwLm0rClTsvx6XMe2 zsegduwv6il9v3ezNudfdkcPtPfptOrkkvHgBfw6VgmvxQA1iuC8XDt/5lTpw/lt hshBRFvKpBTp0x52nkvBs7b7qO8qM55hEZF7NISJOyLbO1VAJPt4zZEFukip+zow QgA556OfDrA5bHDmuYIChBkJFOKeTI7J8DYQy65vloowg6OpkYg= =r2Wn -----END PGP SIGNATURE----- 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>
This commit is contained in:
Коммит
1395f8df87
|
@ -274,7 +274,7 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
|
|||
success = !!(info->flags & IEEE80211_TX_STAT_ACK);
|
||||
|
||||
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
|
||||
if (ar[i].idx < 0)
|
||||
if (ar[i].idx < 0 || !ar[i].count)
|
||||
break;
|
||||
|
||||
ndx = rix_to_ndx(mi, ar[i].idx);
|
||||
|
@ -287,12 +287,6 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
|
|||
mi->r[ndx].stats.success += success;
|
||||
}
|
||||
|
||||
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0))
|
||||
mi->sample_packets++;
|
||||
|
||||
if (mi->sample_deferred > 0)
|
||||
mi->sample_deferred--;
|
||||
|
||||
if (time_after(jiffies, mi->last_stats_update +
|
||||
mp->update_interval / (mp->new_avg ? 2 : 1)))
|
||||
minstrel_update_stats(mp, mi);
|
||||
|
@ -367,7 +361,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
|
|||
return;
|
||||
|
||||
delta = (mi->total_packets * sampling_ratio / 100) -
|
||||
(mi->sample_packets + mi->sample_deferred / 2);
|
||||
mi->sample_packets;
|
||||
|
||||
/* delta < 0: no sampling required */
|
||||
prev_sample = mi->prev_sample;
|
||||
|
@ -376,7 +370,6 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
|
|||
return;
|
||||
|
||||
if (mi->total_packets >= 10000) {
|
||||
mi->sample_deferred = 0;
|
||||
mi->sample_packets = 0;
|
||||
mi->total_packets = 0;
|
||||
} else if (delta > mi->n_rates * 2) {
|
||||
|
@ -401,19 +394,8 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
|
|||
* rate sampling method should be used.
|
||||
* Respect such rates that are not sampled for 20 interations.
|
||||
*/
|
||||
if (mrr_capable &&
|
||||
msr->perfect_tx_time > mr->perfect_tx_time &&
|
||||
msr->stats.sample_skipped < 20) {
|
||||
/* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark
|
||||
* packets that have the sampling rate deferred to the
|
||||
* second MRR stage. Increase the sample counter only
|
||||
* if the deferred sample rate was actually used.
|
||||
* Use the sample_deferred counter to make sure that
|
||||
* the sampling is not done in large bursts */
|
||||
info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
|
||||
rate++;
|
||||
mi->sample_deferred++;
|
||||
} else {
|
||||
if (msr->perfect_tx_time < mr->perfect_tx_time ||
|
||||
msr->stats.sample_skipped >= 20) {
|
||||
if (!msr->sample_limit)
|
||||
return;
|
||||
|
||||
|
@ -433,6 +415,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
|
|||
|
||||
rate->idx = mi->r[ndx].rix;
|
||||
rate->count = minstrel_get_retry_count(&mi->r[ndx], info);
|
||||
info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -126,7 +126,6 @@ struct minstrel_sta_info {
|
|||
u8 max_prob_rate;
|
||||
unsigned int total_packets;
|
||||
unsigned int sample_packets;
|
||||
int sample_deferred;
|
||||
|
||||
unsigned int sample_row;
|
||||
unsigned int sample_column;
|
||||
|
|
|
@ -705,7 +705,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
|
|||
out_drop_sta:
|
||||
local->num_sta--;
|
||||
synchronize_net();
|
||||
__cleanup_single_sta(sta);
|
||||
cleanup_single_sta(sta);
|
||||
out_err:
|
||||
mutex_unlock(&local->sta_mtx);
|
||||
kfree(sinfo);
|
||||
|
@ -724,19 +724,13 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
|
|||
|
||||
err = sta_info_insert_check(sta);
|
||||
if (err) {
|
||||
sta_info_free(local, sta);
|
||||
mutex_unlock(&local->sta_mtx);
|
||||
rcu_read_lock();
|
||||
goto out_free;
|
||||
return err;
|
||||
}
|
||||
|
||||
err = sta_info_insert_finish(sta);
|
||||
if (err)
|
||||
goto out_free;
|
||||
|
||||
return 0;
|
||||
out_free:
|
||||
sta_info_free(local, sta);
|
||||
return err;
|
||||
return sta_info_insert_finish(sta);
|
||||
}
|
||||
|
||||
int sta_info_insert(struct sta_info *sta)
|
||||
|
|
|
@ -49,7 +49,8 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
|
|||
int ac;
|
||||
|
||||
if (info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
|
||||
IEEE80211_TX_CTL_AMPDU)) {
|
||||
IEEE80211_TX_CTL_AMPDU |
|
||||
IEEE80211_TX_CTL_HW_80211_ENCAP)) {
|
||||
ieee80211_free_txskb(&local->hw, skb);
|
||||
return;
|
||||
}
|
||||
|
@ -915,15 +916,6 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
|
|||
ieee80211_mpsp_trigger_process(
|
||||
ieee80211_get_qos_ctl(hdr), sta, true, acked);
|
||||
|
||||
if (!acked && test_sta_flag(sta, WLAN_STA_PS_STA)) {
|
||||
/*
|
||||
* The STA is in power save mode, so assume
|
||||
* that this TX packet failed because of that.
|
||||
*/
|
||||
ieee80211_handle_filtered_frame(local, sta, skb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL) &&
|
||||
(ieee80211_is_data(hdr->frame_control)) &&
|
||||
(rates_idx != -1))
|
||||
|
@ -1150,6 +1142,12 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
|
|||
-info->status.ack_signal);
|
||||
}
|
||||
} else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
|
||||
/*
|
||||
* The STA is in power save mode, so assume
|
||||
* that this TX packet failed because of that.
|
||||
*/
|
||||
if (skb)
|
||||
ieee80211_handle_filtered_frame(local, sta, skb);
|
||||
return;
|
||||
} else if (noack_success) {
|
||||
/* nothing to do here, do not account as lost */
|
||||
|
|
|
@ -876,6 +876,9 @@ static int rfkill_resume(struct device *dev)
|
|||
|
||||
rfkill->suspended = false;
|
||||
|
||||
if (!rfkill->registered)
|
||||
return 0;
|
||||
|
||||
if (!rfkill->persistent) {
|
||||
cur = !!(rfkill->state & RFKILL_BLOCK_SW);
|
||||
rfkill_set_block(rfkill, cur);
|
||||
|
|
Загрузка…
Ссылка в новой задаче