From e5550ed58fc8e6ef03a026814421e02e8d44f925 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Tue, 27 Apr 2021 17:33:37 -0500 Subject: [PATCH] netdev: Detect netdev going down early In case the netdev is brought down while we're trying to connect, try to detect this and fail early instead of trying to send additional commands. src/station.c:station_enter_state() Old State: disconnected, new state: connecting src/station.c:station_netdev_event() Associating src/netdev.c:netdev_mlme_notify() MLME notification Connect(46) src/netdev.c:netdev_connect_event() src/netdev.c:netdev_link_notify() event 16 on ifindex 4 src/eapol.c:eapol_handle_ptk_1_of_4() ifindex=4 src/netdev.c:netdev_link_notify() event 16 on ifindex 4 src/eapol.c:eapol_handle_ptk_3_of_4() ifindex=4 src/netdev.c:netdev_set_gtk() 4 src/station.c:station_handshake_event() Setting keys src/netdev.c:netdev_set_tk() 4 src/netdev.c:netdev_set_rekey_offload() 4 New Key for Group Key failed for ifindex: 4:Network is down src/netdev.c:netdev_link_notify() event 16 on ifindex 4 src/station.c:station_free() src/netdev.c:netdev_mlme_notify() MLME notification Disconnect(48) src/netdev.c:netdev_disconnect_event() src/wiphy.c:wiphy_reg_notify() Notification of command Reg Change(36) src/wiphy.c:wiphy_update_reg_domain() New reg domain country code for (global) is XX src/netdev.c:netdev_link_notify() event 16 on ifindex 4 src/wiphy.c:wiphy_reg_notify() Notification of command Reg Change(36) src/wiphy.c:wiphy_update_reg_domain() New reg domain country code for (global) is DE src/wiphy.c:wiphy_radio_work_done() Work item 14 done src/station.c:station_connect_cb() 4, result: 4 Segmentation fault --- src/netdev.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/netdev.c b/src/netdev.c index 88e579fc..c959d728 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -1309,12 +1309,20 @@ static void netdev_setting_keys_failed(struct netdev_handshake_state *nhs, netdev->group_handshake_timeout = NULL; } - netdev->result = NETDEV_RESULT_KEY_SETTING_FAILED; - handshake_event(&nhs->super, HANDSHAKE_EVENT_SETTING_KEYS_FAILED, &err); - switch (netdev->type) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: + /* + * If we failed due to the netdev being brought down, + * just abort the connection and do not try to send a + * CMD_DISCONNECT + */ + if (err == -ENETDOWN) { + netdev_connect_failed(netdev, NETDEV_RESULT_ABORTED, + MMPDU_STATUS_CODE_UNSPECIFIED); + return; + } + msg = netdev_build_cmd_disconnect(netdev, MMPDU_REASON_CODE_UNSPECIFIED); netdev->disconnect_cmd_id = l_genl_family_send(nl80211, msg, @@ -1322,11 +1330,19 @@ static void netdev_setting_keys_failed(struct netdev_handshake_state *nhs, netdev, NULL); break; case NL80211_IFTYPE_AP: + if (err == -ENETDOWN) + return; + msg = netdev_build_cmd_del_station(netdev, nhs->super.spa, MMPDU_REASON_CODE_UNSPECIFIED, false); if (!l_genl_family_send(nl80211, msg, NULL, NULL, NULL)) l_error("error sending DEL_STATION"); + + break; } + + netdev->result = NETDEV_RESULT_KEY_SETTING_FAILED; + handshake_event(&nhs->super, HANDSHAKE_EVENT_SETTING_KEYS_FAILED, &err); } static void try_handshake_complete(struct netdev_handshake_state *nhs)