Commit 054c9939 authored by Johannes Berg's avatar Johannes Berg

mac80211: pause TX while changing interface type

syzbot reported a crash that happened when changing the interface
type around a lot, and while it might have been easy to fix just
the symptom there, a little deeper investigation found that really
the reason is that we allowed packets to be transmitted while in
the middle of changing the interface type.

Disallow TX by stopping the queues while changing the type.

Fixes: 34d4bc4d ("mac80211: support runtime interface type changes")
Reported-by: syzbot+d7a3b15976bf7de2238a@syzkaller.appspotmail.com
Link: https://lore.kernel.org/r/20210122171115.b321f98f4d4f.I6997841933c17b093535c31d29355be3c0c39628@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 51225651
...@@ -1078,6 +1078,7 @@ enum queue_stop_reason { ...@@ -1078,6 +1078,7 @@ enum queue_stop_reason {
IEEE80211_QUEUE_STOP_REASON_FLUSH, IEEE80211_QUEUE_STOP_REASON_FLUSH,
IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN, IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN,
IEEE80211_QUEUE_STOP_REASON_RESERVE_TID, IEEE80211_QUEUE_STOP_REASON_RESERVE_TID,
IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE,
IEEE80211_QUEUE_STOP_REASONS, IEEE80211_QUEUE_STOP_REASONS,
}; };
......
...@@ -1617,6 +1617,10 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, ...@@ -1617,6 +1617,10 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
if (ret) if (ret)
return ret; return ret;
ieee80211_stop_vif_queues(local, sdata,
IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE);
synchronize_net();
ieee80211_do_stop(sdata, false); ieee80211_do_stop(sdata, false);
ieee80211_teardown_sdata(sdata); ieee80211_teardown_sdata(sdata);
...@@ -1639,6 +1643,8 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, ...@@ -1639,6 +1643,8 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
err = ieee80211_do_open(&sdata->wdev, false); err = ieee80211_do_open(&sdata->wdev, false);
WARN(err, "type change: do_open returned %d", err); WARN(err, "type change: do_open returned %d", err);
ieee80211_wake_vif_queues(local, sdata,
IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment