From e295b73c4c57616717b72745ddefc5519d97192d Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Fri, 8 Mar 2019 16:09:42 -0600 Subject: [PATCH] netdev: Fix crash when aborting a connection We can crash if we abort the connection, but the connect command has already gone through. In this case we will get a sequence of authenticate_event, associate_event, connect_event. The first and last events don't crash since they check whether netdev->connected is true. However, this causes an annoying warning to be printed. Fix this by introducing an 'aborting' flag and ignore all connection related events if it is set. ++++++++ backtrace ++++++++ --- src/netdev.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/netdev.c b/src/netdev.c index 7acd7edb..83fab899 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -137,6 +137,7 @@ struct netdev { bool use_4addr : 1; bool ignore_connect_event : 1; bool expect_connect_failure : 1; + bool aborting : 1; }; struct netdev_preauth_state { @@ -943,6 +944,7 @@ static void netdev_cmd_disconnect_cb(struct l_genl_msg *msg, void *user_data) bool r; netdev->disconnect_cmd_id = 0; + netdev->aborting = false; if (!netdev->disconnect_cb) { netdev->user_data = NULL; @@ -1747,6 +1749,9 @@ static void netdev_connect_event(struct l_genl_msg *msg, struct netdev *netdev) l_debug(""); + if (netdev->aborting) + return; + if (netdev->ignore_connect_event) return; @@ -2255,6 +2260,9 @@ static void netdev_authenticate_event(struct l_genl_msg *msg, l_debug(""); + if (netdev->aborting) + return; + if (!netdev->connected) { l_warn("Unexpected connection related event -- " "is another supplicant running?"); @@ -2331,6 +2339,9 @@ static void netdev_associate_event(struct l_genl_msg *msg, l_debug(""); + if (netdev->aborting) + return; + if (!l_genl_attr_init(&attr, msg)) { l_debug("attr init failed"); return; @@ -2872,6 +2883,11 @@ int netdev_disconnect(struct netdev *netdev, /* Only perform this if we haven't successfully fully associated yet */ if (!netdev->operational) { + if (netdev->connect_cmd_id) { + l_genl_family_cancel(nl80211, netdev->connect_cmd_id); + netdev->connect_cmd_id = 0; + } + netdev_connect_failed(netdev, NETDEV_RESULT_ABORTED, MMPDU_REASON_CODE_UNSPECIFIED); } else { @@ -2890,6 +2906,7 @@ int netdev_disconnect(struct netdev *netdev, netdev->disconnect_cb = cb; netdev->user_data = user_data; + netdev->aborting = true; return 0; }