Message ID | 20221025123250.143952-1-shaozhengchao@huawei.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | wifi: mac80211: fix general-protection-fault in ieee80211_subif_start_xmit() | expand |
On 25.10.22 14:32, Zhengchao Shao wrote: > When device is running and the interface status is changed, the gpf issue > is triggered. The problem triggering process is as follows: > Thread A: Thread B > ieee80211_runtime_change_iftype() process_one_work() > ... ... > ieee80211_do_stop() ... > ... ... > sdata->bss = NULL ... > ... ieee80211_subif_start_xmit() > ieee80211_multicast_to_unicast > //!sdata->bss->multicast_to_unicast > cause gpf issue > > When the interface status is changed, the sending queue continues to send > packets. After the bss is set to NULL, the bss is accessed. As a result, > this causes a general-protection-fault issue. > > The following is the stack information: > general protection fault, probably for non-canonical address > 0xdffffc000000002f: 0000 [#1] PREEMPT SMP KASAN > KASAN: null-ptr-deref in range [0x0000000000000178-0x000000000000017f] > Workqueue: mld mld_ifc_work > RIP: 0010:ieee80211_subif_start_xmit+0x25b/0x1310 > Call Trace: > <TASK> > dev_hard_start_xmit+0x1be/0x990 > __dev_queue_xmit+0x2c9a/0x3b60 > ip6_finish_output2+0xf92/0x1520 > ip6_finish_output+0x6af/0x11e0 > ip6_output+0x1ed/0x540 > mld_sendpack+0xa09/0xe70 > mld_ifc_work+0x71c/0xdb0 > process_one_work+0x9bf/0x1710 > worker_thread+0x665/0x1080 > kthread+0x2e4/0x3a0 > ret_from_fork+0x1f/0x30 > </TASK> > > Fixes: 107395f9cf44 ("wifi: mac80211: Drop support for TX push path") Don't think this patch fixes an issue introduced with the patch you refer to. This patch changed nothing from a flow perspective and is just cleaning up unused code. It still may still make sense to refer to the series: It next to be sure triggered the issue for at least one driver (I assume it was hwsim here.) That said this seems to be more related to whatever caused this bug: f856373e2f31 ("wifi: mac80211: do not wake queues on a vif that is being stopped") > Reported-by: syzbot+c6e8fca81c294fd5620a@syzkaller.appspotmail.com > Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com> > --- > net/mac80211/iface.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c > index dd9ac1f7d2ea..5a924459bfd1 100644 > --- a/net/mac80211/iface.c > +++ b/net/mac80211/iface.c > @@ -1900,6 +1900,9 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, > IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE); > synchronize_net(); > > + if (sdata->dev) > + netif_tx_stop_all_queues(sdata->dev); All mac80211 interfaces are now non-queuing interfaces. When you stop the netif queues for a non-queuing interface netdev will warn about that. To avoid that you have to replace the netif call with clear_bit(SDATA_STATE_RUNNING, &sdata->state); Should just work the same for you here. > + > ieee80211_do_stop(sdata, false); > > ieee80211_teardown_sdata(sdata); > @@ -1922,6 +1925,9 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, > err = ieee80211_do_open(&sdata->wdev, false); > WARN(err, "type change: do_open returned %d", err); > > + if (sdata->dev) > + netif_tx_start_all_queues(sdata->dev); That must then be of course set_bit(SDATA_STATE_RUNNING, &sdata->state); > + > ieee80211_wake_vif_queues(local, sdata, > IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE); > return ret; Alexander
On 2022/10/25 22:42, Alexander Wetzel wrote: > On 25.10.22 14:32, Zhengchao Shao wrote: >> When device is running and the interface status is changed, the gpf issue >> is triggered. The problem triggering process is as follows: >> Thread A: Thread B >> ieee80211_runtime_change_iftype() process_one_work() >> ... ... >> ieee80211_do_stop() ... >> ... ... >> sdata->bss = NULL ... >> ... ieee80211_subif_start_xmit() >> >> ieee80211_multicast_to_unicast >> //!sdata->bss->multicast_to_unicast >> cause gpf issue >> >> When the interface status is changed, the sending queue continues to send >> packets. After the bss is set to NULL, the bss is accessed. As a result, >> this causes a general-protection-fault issue. >> >> The following is the stack information: >> general protection fault, probably for non-canonical address >> 0xdffffc000000002f: 0000 [#1] PREEMPT SMP KASAN >> KASAN: null-ptr-deref in range [0x0000000000000178-0x000000000000017f] >> Workqueue: mld mld_ifc_work >> RIP: 0010:ieee80211_subif_start_xmit+0x25b/0x1310 >> Call Trace: >> <TASK> >> dev_hard_start_xmit+0x1be/0x990 >> __dev_queue_xmit+0x2c9a/0x3b60 >> ip6_finish_output2+0xf92/0x1520 >> ip6_finish_output+0x6af/0x11e0 >> ip6_output+0x1ed/0x540 >> mld_sendpack+0xa09/0xe70 >> mld_ifc_work+0x71c/0xdb0 >> process_one_work+0x9bf/0x1710 >> worker_thread+0x665/0x1080 >> kthread+0x2e4/0x3a0 >> ret_from_fork+0x1f/0x30 >> </TASK> >> >> Fixes: 107395f9cf44 ("wifi: mac80211: Drop support for TX push path") > > Don't think this patch fixes an issue introduced with the patch you > refer to. This patch changed nothing from a flow perspective and is just > cleaning up unused code. > It still may still make sense to refer to the series: It next to be sure > triggered the issue for at least one driver (I assume it was hwsim here.) > > That said this seems to be more related to whatever caused this bug: > f856373e2f31 ("wifi: mac80211: do not wake queues on a vif that is being > stopped") > > >> Reported-by: syzbot+c6e8fca81c294fd5620a@syzkaller.appspotmail.com >> Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com> >> --- >> net/mac80211/iface.c | 6 ++++++ >> 1 file changed, 6 insertions(+) >> >> diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c >> index dd9ac1f7d2ea..5a924459bfd1 100644 >> --- a/net/mac80211/iface.c >> +++ b/net/mac80211/iface.c >> @@ -1900,6 +1900,9 @@ static int >> ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, >> IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE); >> synchronize_net(); >> + if (sdata->dev) >> + netif_tx_stop_all_queues(sdata->dev); > > All mac80211 interfaces are now non-queuing interfaces. > When you stop the netif queues for a non-queuing interface netdev will > warn about that. > > To avoid that you have to replace the netif call with > clear_bit(SDATA_STATE_RUNNING, &sdata->state); > > Should just work the same for you here. >> + >> ieee80211_do_stop(sdata, false); >> ieee80211_teardown_sdata(sdata); >> @@ -1922,6 +1925,9 @@ static int >> ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, >> err = ieee80211_do_open(&sdata->wdev, false); >> WARN(err, "type change: do_open returned %d", err); >> + if (sdata->dev) >> + netif_tx_start_all_queues(sdata->dev); > > That must then be of course > set_bit(SDATA_STATE_RUNNING, &sdata->state); > > >> + >> ieee80211_wake_vif_queues(local, sdata, >> IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE); >> return ret; > > Alexander Hi Alexander: Thank you for your review. I will fix them in V2. Zhengchao Shao
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index dd9ac1f7d2ea..5a924459bfd1 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1900,6 +1900,9 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE); synchronize_net(); + if (sdata->dev) + netif_tx_stop_all_queues(sdata->dev); + ieee80211_do_stop(sdata, false); ieee80211_teardown_sdata(sdata); @@ -1922,6 +1925,9 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, err = ieee80211_do_open(&sdata->wdev, false); WARN(err, "type change: do_open returned %d", err); + if (sdata->dev) + netif_tx_start_all_queues(sdata->dev); + ieee80211_wake_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE); return ret;
When device is running and the interface status is changed, the gpf issue is triggered. The problem triggering process is as follows: Thread A: Thread B ieee80211_runtime_change_iftype() process_one_work() ... ... ieee80211_do_stop() ... ... ... sdata->bss = NULL ... ... ieee80211_subif_start_xmit() ieee80211_multicast_to_unicast //!sdata->bss->multicast_to_unicast cause gpf issue When the interface status is changed, the sending queue continues to send packets. After the bss is set to NULL, the bss is accessed. As a result, this causes a general-protection-fault issue. The following is the stack information: general protection fault, probably for non-canonical address 0xdffffc000000002f: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000178-0x000000000000017f] Workqueue: mld mld_ifc_work RIP: 0010:ieee80211_subif_start_xmit+0x25b/0x1310 Call Trace: <TASK> dev_hard_start_xmit+0x1be/0x990 __dev_queue_xmit+0x2c9a/0x3b60 ip6_finish_output2+0xf92/0x1520 ip6_finish_output+0x6af/0x11e0 ip6_output+0x1ed/0x540 mld_sendpack+0xa09/0xe70 mld_ifc_work+0x71c/0xdb0 process_one_work+0x9bf/0x1710 worker_thread+0x665/0x1080 kthread+0x2e4/0x3a0 ret_from_fork+0x1f/0x30 </TASK> Fixes: 107395f9cf44 ("wifi: mac80211: Drop support for TX push path") Reported-by: syzbot+c6e8fca81c294fd5620a@syzkaller.appspotmail.com Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com> --- net/mac80211/iface.c | 6 ++++++ 1 file changed, 6 insertions(+)