From patchwork Thu Jan 21 15:40:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Otcheretianski, Andrei" X-Patchwork-Id: 1429923 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=MF/pydzX; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DM68c1lCLz9sW1 for ; Fri, 22 Jan 2021 02:42:24 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=TIZ6hRpnaRe+UTv4YC04AvzlNocOOdqbywGPNFovUSs=; b=MF/pydzXP2/hYq9XcguCVSum8 EPFnhDZZnKQEbuIOjCvC5qnFVEPVxhzojKBuKmu3LNgZyjyPWw3whrOBALMxcUHhnXjSMKYVz1ods IGJcB0Aobm7EJyKLLSLkrWpiXZfRDICCzRYYdr9I+lalHR7e9wtGtVmGwRIxbBeWpbMbOrpGEfsi9 kTZwf/TtXAleLshr1xQIttsJKAWG4z9SoAw8rrS9mqWrJxYyeGApmSVbyJD9JRblQgZ6ANWmTvyRL dZWyxjnMEd+bBkQchaeqJqPOW4yLuvGkL/3Mt04p+DMCd2bX3cg/8bUqga6GAtXrrKGEXbvzmRWrx GjIHm6fFA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l2c5I-0000DX-F6; Thu, 21 Jan 2021 15:41:20 +0000 Received: from mga18.intel.com ([134.134.136.126]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l2c5G-0000Cg-3n for hostap@lists.infradead.org; Thu, 21 Jan 2021 15:41:19 +0000 IronPort-SDR: jiRrNryTuQ7ycy8MdNo89q5WZOKlvBlIG8Q1Ar5GtcpKHmHFdEFxkco2IA8NYIDILSswf4wE03 g//TJ4O7fMnw== X-IronPort-AV: E=McAfee;i="6000,8403,9870"; a="166958661" X-IronPort-AV: E=Sophos;i="5.79,364,1602572400"; d="scan'208";a="166958661" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jan 2021 07:41:15 -0800 IronPort-SDR: WWgJWVvP3MM+Hblego/6+VNi1lGGszgbXkD2XnB3cyc7D97/o7e8aFlUoe0uqw6jbHrWckj4ns XDA6gm7zmE+w== X-IronPort-AV: E=Sophos;i="5.79,364,1602572400"; d="scan'208";a="385350132" Received: from ramilaux-mobl2.ger.corp.intel.com (HELO aotchere-desk.ger.corp.intel.com) ([10.214.246.158]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jan 2021 07:41:13 -0800 From: Andrei Otcheretianski To: hostap@lists.infradead.org Subject: [PATCH] nl80211: use the process_bss_event for the nl_connect handler Date: Thu, 21 Jan 2021 17:40:34 +0200 Message-Id: <20210121154037.32654-3-andrei.otcheretianski@intel.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20210121154037.32654-1-andrei.otcheretianski@intel.com> References: <20210121154037.32654-1-andrei.otcheretianski@intel.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210121_104118_319990_320E8F6A X-CRM114-Status: GOOD ( 19.49 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [134.134.136.126 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Avraham Stern Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Avraham Stern The nl_connect is initialized with the process_bss_event() handler. However, it is used several times with the default valid handler. As a result, if a message that is only valid for the process_bss_event() is received while the default handler is used, it will be dropped. This has been observed in a case where during the 4 way handshake, a beacon is received on the AP side, which triggers a beacon update, just before receiving the next EAPOL. When send_and_recv_msgs_owner() is called for sending the NL80211_CMD_SET_BEACON command, the NL80211_CMD_CONTROL_PORT_FRAME event is already pending. As a result, it is received with the default handler, which drops it. Since the EAPOL frame is dropped, the connection attempt fails. Fix it by using the process_bss_event() handler when the nl_connect handler is used. Signed-off-by: Avraham Stern --- src/drivers/driver_nl80211.c | 75 +++++++++++++++---------------- src/drivers/driver_nl80211.h | 2 +- src/drivers/driver_nl80211_scan.c | 2 +- 3 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 13ecd11d3f..3a78380172 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -530,6 +530,21 @@ static int send_and_recv_msgs_owner(struct wpa_driver_nl80211_data *drv, } +static int +send_and_recv_msgs_connect_handle(struct wpa_driver_nl80211_data *drv, + struct nl_msg *msg, struct i802_bss *bss) +{ + struct nl_sock *nl_connect = get_connect_handle(bss); + + if (nl_connect) + return send_and_recv_msgs_owner(drv, msg, nl_connect, 1, + process_bss_event, bss, NULL, + NULL); + else + return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); +} + + struct nl_sock * get_connect_handle(struct i802_bss *bss) { if ((bss->drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) || @@ -3515,10 +3530,11 @@ static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params, int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv, const u8 *addr, int cmd, u16 reason_code, int local_state_change, - struct nl_sock *nl_connect) + struct i802_bss *bss) { int ret; struct nl_msg *msg; + struct nl_sock *nl_connect = get_connect_handle(bss); if (!(msg = nl80211_drv_msg(drv, 0, cmd)) || nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code) || @@ -3530,8 +3546,8 @@ int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv, } if (nl_connect) - ret = send_and_recv(drv->global, nl_connect, msg, NULL, NULL, - NULL, NULL); + ret = send_and_recv(drv->global, nl_connect, msg, + process_bss_event, bss, NULL, NULL); else ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); if (ret) { @@ -3545,7 +3561,7 @@ int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv, static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv, u16 reason_code, - struct nl_sock *nl_connect) + struct i802_bss *bss) { int ret; int drv_associated = drv->associated; @@ -3554,7 +3570,7 @@ static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv, nl80211_mark_disconnected(drv); /* Disconnect command doesn't need BSSID - it uses cached value */ ret = wpa_driver_nl80211_mlme(drv, NULL, NL80211_CMD_DISCONNECT, - reason_code, 0, nl_connect); + reason_code, 0, bss); /* * For locally generated disconnect, supplicant already generates a * DEAUTH event, so ignore the event from NL80211. @@ -3577,14 +3593,13 @@ static int wpa_driver_nl80211_deauthenticate(struct i802_bss *bss, return nl80211_leave_ibss(drv, 1); } if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) { - return wpa_driver_nl80211_disconnect(drv, reason_code, - get_connect_handle(bss)); + return wpa_driver_nl80211_disconnect(drv, reason_code, bss); } wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)", __func__, MAC2STR(addr), reason_code); nl80211_mark_disconnected(drv); ret = wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE, - reason_code, 0, get_connect_handle(bss)); + reason_code, 0, bss); /* * For locally generated deauthenticate, supplicant already generates a * DEAUTH event, so ignore the event from NL80211. @@ -4604,15 +4619,7 @@ static int wpa_driver_nl80211_set_ap(void *priv, } #endif /* CONFIG_IEEE80211AX */ -#ifdef CONFIG_SAE - if (((params->key_mgmt_suites & WPA_KEY_MGMT_SAE) || - (params->key_mgmt_suites & WPA_KEY_MGMT_FT_SAE)) && - nl80211_put_sae_pwe(msg, params->sae_pwe) < 0) - goto fail; -#endif /* CONFIG_SAE */ - - ret = send_and_recv_msgs_owner(drv, msg, get_connect_handle(bss), 1, - NULL, NULL, NULL, NULL); + ret = send_and_recv_msgs_connect_handle(drv, msg, bss); if (ret) { wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)", ret, strerror(-ret)); @@ -5652,9 +5659,7 @@ static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv, int ret; msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_IBSS); - ret = send_and_recv_msgs_owner(drv, msg, - get_connect_handle(drv->first_bss), 1, - NULL, NULL, NULL, NULL); + ret = send_and_recv_msgs_connect_handle(drv, msg, drv->first_bss); if (ret) { wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d " "(%s)", ret, strerror(-ret)); @@ -5786,9 +5791,7 @@ retry: if (ret < 0) goto fail; - ret = send_and_recv_msgs_owner(drv, msg, - get_connect_handle(drv->first_bss), 1, - NULL, NULL, NULL, NULL); + ret = send_and_recv_msgs_connect_handle(drv, msg, drv->first_bss); msg = NULL; if (ret) { wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)", @@ -6124,7 +6127,7 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv, static int wpa_driver_nl80211_try_connect( struct wpa_driver_nl80211_data *drv, struct wpa_driver_associate_params *params, - struct nl_sock *nl_connect) + struct i802_bss *bss) { struct nl_msg *msg; enum nl80211_auth_type type; @@ -6196,8 +6199,7 @@ skip_auth_type: if (ret) goto fail; - ret = send_and_recv_msgs_owner(drv, msg, nl_connect, 1, NULL, - (void *) -1, NULL, NULL); + ret = send_and_recv_msgs_connect_handle(drv, msg, bss); msg = NULL; if (ret) { wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d " @@ -6221,7 +6223,7 @@ fail: static int wpa_driver_nl80211_connect( struct wpa_driver_nl80211_data *drv, struct wpa_driver_associate_params *params, - struct nl_sock *nl_connect) + struct i802_bss *bss) { int ret; @@ -6231,7 +6233,7 @@ static int wpa_driver_nl80211_connect( else os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN); - ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect); + ret = wpa_driver_nl80211_try_connect(drv, params, bss); if (ret == -EALREADY) { /* * cfg80211 does not currently accept new connections if @@ -6242,9 +6244,9 @@ static int wpa_driver_nl80211_connect( "disconnecting before reassociation " "attempt"); if (wpa_driver_nl80211_disconnect( - drv, WLAN_REASON_PREV_AUTH_NOT_VALID, nl_connect)) + drv, WLAN_REASON_PREV_AUTH_NOT_VALID, bss)) return -1; - ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect); + ret = wpa_driver_nl80211_try_connect(drv, params, bss); } return ret; } @@ -6278,8 +6280,7 @@ static int wpa_driver_nl80211_associate( else bss->use_nl_connect = 0; - return wpa_driver_nl80211_connect(drv, params, - get_connect_handle(bss)); + return wpa_driver_nl80211_connect(drv, params, bss); } nl80211_mark_disconnected(drv); @@ -6314,9 +6315,7 @@ static int wpa_driver_nl80211_associate( goto fail; } - ret = send_and_recv_msgs_owner(drv, msg, - get_connect_handle(drv->first_bss), 1, - NULL, NULL, NULL, NULL); + ret = send_and_recv_msgs_connect_handle(drv, msg, drv->first_bss); msg = NULL; if (ret) { wpa_dbg(drv->ctx, MSG_DEBUG, @@ -10299,8 +10298,7 @@ static int nl80211_join_mesh(struct i802_bss *bss, if (nl80211_put_mesh_config(msg, ¶ms->conf) < 0) goto fail; - ret = send_and_recv_msgs_owner(drv, msg, get_connect_handle(bss), 1, - NULL, NULL, NULL, NULL); + ret = send_and_recv_msgs_connect_handle(drv, msg, bss); msg = NULL; if (ret) { wpa_printf(MSG_DEBUG, "nl80211: mesh join failed: ret=%d (%s)", @@ -10357,8 +10355,7 @@ static int wpa_driver_nl80211_leave_mesh(void *priv) wpa_printf(MSG_DEBUG, "nl80211: mesh leave (ifindex=%d)", drv->ifindex); msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_MESH); - ret = send_and_recv_msgs_owner(drv, msg, get_connect_handle(bss), 0, - NULL, NULL, NULL, NULL); + ret = send_and_recv_msgs_connect_handle(drv, msg, bss); if (ret) { wpa_printf(MSG_DEBUG, "nl80211: mesh leave failed: ret=%d (%s)", ret, strerror(-ret)); diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index 7b9be1f3a9..924064fd76 100644 --- a/src/drivers/driver_nl80211.h +++ b/src/drivers/driver_nl80211.h @@ -270,7 +270,7 @@ int wpa_driver_nl80211_set_mode(struct i802_bss *bss, int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv, const u8 *addr, int cmd, u16 reason_code, int local_state_change, - struct nl_sock *nl_connect); + struct i802_bss *bss); int nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv); void nl80211_remove_monitor_interface(struct wpa_driver_nl80211_data *drv); diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c index 233175d19b..1316084805 100644 --- a/src/drivers/driver_nl80211_scan.c +++ b/src/drivers/driver_nl80211_scan.c @@ -870,7 +870,7 @@ static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv, wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE, WLAN_REASON_PREV_AUTH_NOT_VALID, 1, - get_connect_handle(drv->first_bss)); + drv->first_bss); } }