3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-18 01:59:31 +01:00

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 ++++++++
This commit is contained in:
Denis Kenzior 2019-03-08 16:09:42 -06:00
parent 1677f6b046
commit e295b73c4c

View File

@ -137,6 +137,7 @@ struct netdev {
bool use_4addr : 1; bool use_4addr : 1;
bool ignore_connect_event : 1; bool ignore_connect_event : 1;
bool expect_connect_failure : 1; bool expect_connect_failure : 1;
bool aborting : 1;
}; };
struct netdev_preauth_state { struct netdev_preauth_state {
@ -943,6 +944,7 @@ static void netdev_cmd_disconnect_cb(struct l_genl_msg *msg, void *user_data)
bool r; bool r;
netdev->disconnect_cmd_id = 0; netdev->disconnect_cmd_id = 0;
netdev->aborting = false;
if (!netdev->disconnect_cb) { if (!netdev->disconnect_cb) {
netdev->user_data = NULL; netdev->user_data = NULL;
@ -1747,6 +1749,9 @@ static void netdev_connect_event(struct l_genl_msg *msg, struct netdev *netdev)
l_debug(""); l_debug("");
if (netdev->aborting)
return;
if (netdev->ignore_connect_event) if (netdev->ignore_connect_event)
return; return;
@ -2255,6 +2260,9 @@ static void netdev_authenticate_event(struct l_genl_msg *msg,
l_debug(""); l_debug("");
if (netdev->aborting)
return;
if (!netdev->connected) { if (!netdev->connected) {
l_warn("Unexpected connection related event -- " l_warn("Unexpected connection related event -- "
"is another supplicant running?"); "is another supplicant running?");
@ -2331,6 +2339,9 @@ static void netdev_associate_event(struct l_genl_msg *msg,
l_debug(""); l_debug("");
if (netdev->aborting)
return;
if (!l_genl_attr_init(&attr, msg)) { if (!l_genl_attr_init(&attr, msg)) {
l_debug("attr init failed"); l_debug("attr init failed");
return; return;
@ -2872,6 +2883,11 @@ int netdev_disconnect(struct netdev *netdev,
/* Only perform this if we haven't successfully fully associated yet */ /* Only perform this if we haven't successfully fully associated yet */
if (!netdev->operational) { 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, netdev_connect_failed(netdev, NETDEV_RESULT_ABORTED,
MMPDU_REASON_CODE_UNSPECIFIED); MMPDU_REASON_CODE_UNSPECIFIED);
} else { } else {
@ -2890,6 +2906,7 @@ int netdev_disconnect(struct netdev *netdev,
netdev->disconnect_cb = cb; netdev->disconnect_cb = cb;
netdev->user_data = user_data; netdev->user_data = user_data;
netdev->aborting = true;
return 0; return 0;
} }