From patchwork Thu Oct 8 09:36:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilan Peer X-Patchwork-Id: 527647 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 0FD35140D87 for ; Thu, 8 Oct 2015 20:39:02 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id B1F139D3C2; Thu, 8 Oct 2015 05:38:01 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yeLq9ctLFyoZ; Thu, 8 Oct 2015 05:38:01 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 2FE3317C383; Thu, 8 Oct 2015 05:36:49 -0400 (EDT) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 4E10117C288 for ; Thu, 8 Oct 2015 05:36:42 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id TNUelZUyKnJS for ; Thu, 8 Oct 2015 05:36:38 -0400 (EDT) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id CBA8A17C2DF for ; Thu, 8 Oct 2015 05:36:33 -0400 (EDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga102.jf.intel.com with ESMTP; 08 Oct 2015 02:36:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,654,1437462000"; d="scan'208";a="822158253" Received: from unknown (HELO JEL00311.ger.corp.intel.com) ([10.12.217.137]) by fmsmga002.fm.intel.com with ESMTP; 08 Oct 2015 02:36:28 -0700 From: Ilan Peer To: hostap@lists.shmoo.com Subject: [PATCH v2 07/12] P2PS: Fix PD Request parameter handling Date: Thu, 8 Oct 2015 12:36:02 +0300 Message-Id: <1444296967-20844-8-git-send-email-ilan.peer@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1444296967-20844-1-git-send-email-ilan.peer@intel.com> References: <1444296967-20844-1-git-send-email-ilan.peer@intel.com> X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com From: Max Stepanov In P2PS PD Request processing in some error case scenarios, such as verification of the WPS config method, the flow aborts before saving mandatory P2PS PD Request attributes. This in turn causes the control interface notification events to be sent with invalid parameters. Fix this by changing the order of verification and processing steps of the PD Request message handling. Signed-off-by: Max Stepanov --- src/p2p/p2p_pd.c | 129 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 59 deletions(-) diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c index 26e0715..10cdbac 100644 --- a/src/p2p/p2p_pd.c +++ b/src/p2p/p2p_pd.c @@ -552,14 +552,14 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, u8 conncap = P2PS_SETUP_NEW; u8 auto_accept = 0; u32 session_id = 0; - u8 session_mac[ETH_ALEN]; - u8 adv_mac[ETH_ALEN]; + u8 session_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; + u8 adv_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; const u8 *group_mac; int passwd_id = DEV_PW_DEFAULT; u16 config_methods; u16 allowed_config_methods = WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD; - struct p2ps_feature_capab resp_fcap = { 0, 0 }; - struct p2ps_feature_capab *req_fcap; + struct p2ps_feature_capab resp_fcap = {0, 0}; + struct p2ps_feature_capab *req_fcap = NULL; u8 remote_conncap; u16 method; @@ -597,43 +597,71 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); } - if (msg.adv_id) - allowed_config_methods |= WPS_CONFIG_P2PS; - else + if (!msg.adv_id) { allowed_config_methods |= WPS_CONFIG_PUSHBUTTON; + if (!(msg.wps_config_methods & allowed_config_methods)) { + p2p_dbg(p2p, "Unsupported Config Methods in Provision Discovery Request"); + goto out; + } - if (!(msg.wps_config_methods & allowed_config_methods)) { - p2p_dbg(p2p, "Unsupported Config Methods in Provision Discovery Request"); - goto out; - } + /* Legacy (non-P2PS) - Unknown groups allowed for P2PS */ + if (msg.group_id) { + size_t i; - /* Legacy (non-P2PS) - Unknown groups allowed for P2PS */ - if (!msg.adv_id && msg.group_id) { - size_t i; - for (i = 0; i < p2p->num_groups; i++) { - if (p2p_group_is_group_id_match(p2p->groups[i], + for (i = 0; i < p2p->num_groups; i++) { + if (p2p_group_is_group_id_match( + p2p->groups[i], msg.group_id, msg.group_id_len)) - break; + break; + } + if (i == p2p->num_groups) { + p2p_dbg(p2p, "PD request for unknown P2P Group ID - reject"); + goto out; + } + } + } else { + /* + * set adv_id here, so in case of an error, a P2PS PD response + * would be sent + */ + adv_id = WPA_GET_LE32(msg.adv_id); + if (p2ps_validate_pd_req(p2p, &msg, sa) < 0) { + reject = P2P_SC_FAIL_INVALID_PARAMS; + goto out; } - if (i == p2p->num_groups) { - p2p_dbg(p2p, "PD request for unknown P2P Group ID - reject"); + + os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN); + session_id = WPA_GET_LE32(msg.session_id); + os_memcpy(session_mac, msg.session_mac, ETH_ALEN); + req_fcap = (struct p2ps_feature_capab *)msg.feature_cap; + if (msg.conn_cap) + conncap = *msg.conn_cap; + + allowed_config_methods |= WPS_CONFIG_P2PS; + + /* + * We need to verify a P2PS config methog in an initial PD + * request or in a follow-on PD request with the status + * SUCCESS_DEFERRED. + */ + if ((!msg.status || *msg.status == P2P_SC_SUCCESS_DEFERRED) && + !(msg.wps_config_methods & allowed_config_methods)) { + p2p_dbg(p2p, + "Unsupported Config Methods in Provision Discovery Request"); goto out; } + + /* + * TODO: since we don't support multiple PD, reject PD request + * if we are in the middle of P2PS PD with some other peer + */ } dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | P2P_DEV_PD_PEER_KEYPAD | P2P_DEV_PD_PEER_P2PS); - /* Remove stale persistent groups */ - if (p2p->cfg->remove_stale_groups) { - p2p->cfg->remove_stale_groups( - p2p->cfg->cb_ctx, dev->info.p2p_device_addr, - msg.persistent_dev, - msg.persistent_ssid, msg.persistent_ssid_len); - } - if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) { p2p_dbg(p2p, "Peer " MACSTR " requested us to show a PIN on display", MAC2STR(sa)); @@ -652,41 +680,28 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, passwd_id = DEV_PW_P2PS_DEFAULT; } - reject = P2P_SC_SUCCESS; + /* Remove stale persistent groups */ + if (p2p->cfg->remove_stale_groups) { + p2p->cfg->remove_stale_groups( + p2p->cfg->cb_ctx, dev->info.p2p_device_addr, + msg.persistent_dev, + msg.persistent_ssid, msg.persistent_ssid_len); + } - os_memset(session_mac, 0, ETH_ALEN); - os_memset(adv_mac, 0, ETH_ALEN); + reject = P2P_SC_SUCCESS; /* - * Validate a P2PS PD Request and skip P2PS processing if not a valid - * P2PS PD. + * End of a legacy P2P PD request processing, from this point continue + * with P2PS one. */ - if (msg.adv_id) { - /* - * Set adv_id here, so that in case of an error, a P2PS PD - * Response will be sent. - */ - adv_id = WPA_GET_LE32(msg.adv_id); - if (p2ps_validate_pd_req(p2p, &msg, sa) < 0) { - reject = P2P_SC_FAIL_INVALID_PARAMS; - goto out; - } - } else { + if (!msg.adv_id) goto out; - } - req_fcap = (struct p2ps_feature_capab *) msg.feature_cap; - - os_memcpy(session_mac, msg.session_mac, ETH_ALEN); - os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN); - - session_id = WPA_GET_LE32(msg.session_id); - - if (msg.conn_cap) - conncap = *msg.conn_cap; remote_conncap = conncap; if (!msg.status) { + int forced_freq, pref_freq; + if (os_memcmp(p2p->cfg->dev_addr, msg.adv_mac, ETH_ALEN)) { p2p_dbg(p2p, "P2PS PD adv mac does not match the local one"); @@ -701,10 +716,6 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, goto out; } p2p_dbg(p2p, "adv_id: 0x%X, p2ps_adv: %p", adv_id, p2ps_adv); - } - - if (p2ps_adv) { - int forced_freq, pref_freq; auto_accept = p2ps_adv->auto_accept; conncap = p2p->cfg->p2ps_group_capability(p2p->cfg->cb_ctx, @@ -712,11 +723,11 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, &forced_freq, &pref_freq); - p2p_prepare_channel(p2p, dev, forced_freq, pref_freq, 0); - p2p_dbg(p2p, "Conncap: local:%d remote:%d result:%d", auto_accept, remote_conncap, conncap); + p2p_prepare_channel(p2p, dev, forced_freq, pref_freq, 0); + resp_fcap.cpt = p2ps_own_preferred_cpt(p2ps_adv->cpt_priority, req_fcap->cpt);