]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Fix provision discovery response handling in some cases
authorJouni Malinen <j@w1.fi>
Sat, 30 Mar 2013 14:10:43 +0000 (16:10 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 30 Mar 2013 14:10:43 +0000 (16:10 +0200)
Commit 6b56cc2d97fe9efd1feea8d418714b4658b056f1 added a possible call to
p2p_reset_pending_pd() prior to checking config_methods match between
our request and peer response. That reset call could clear
dev->req_config_methods and as such, result in unexpected
P2P-PROV-DISC-FAILURE report here even in cases where the peer accepts
the provision discovery. Fix this by using a local copy of the
req_config_methods variable.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/p2p/p2p_pd.c

index d8f33b1b62f4999d4badf99158462dca3404eaec..a1268e44925767a7e929249dc1a1c1e456fad1d1 100644 (file)
@@ -259,7 +259,7 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
 {
        struct p2p_message msg;
        struct p2p_device *dev;
-       u16 report_config_methods = 0;
+       u16 report_config_methods = 0, req_config_methods;
        int success = 0;
 
        if (p2p_parse(data, len, &msg))
@@ -293,6 +293,12 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
                p2p->pending_action_state = P2P_NO_PENDING_ACTION;
        }
 
+       /*
+        * Use a local copy of the requested config methods since
+        * p2p_reset_pending_pd() can clear this in the peer entry.
+        */
+       req_config_methods = dev->req_config_methods;
+
        /*
         * If the response is from the peer to whom a user initiated request
         * was sent earlier, we reset that state info here.
@@ -301,9 +307,11 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
            os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0)
                p2p_reset_pending_pd(p2p);
 
-       if (msg.wps_config_methods != dev->req_config_methods) {
+       if (msg.wps_config_methods != req_config_methods) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer rejected "
-                       "our Provision Discovery Request");
+                       "our Provision Discovery Request (received "
+                       "config_methods 0x%x expected 0x%x",
+                       msg.wps_config_methods, req_config_methods);
                if (p2p->cfg->prov_disc_fail)
                        p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
                                                 P2P_PROV_DISC_REJECTED);
@@ -311,10 +319,10 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
                goto out;
        }
 
-       report_config_methods = dev->req_config_methods;
+       report_config_methods = req_config_methods;
        dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
                        P2P_DEV_PD_PEER_KEYPAD);
-       if (dev->req_config_methods & WPS_CONFIG_DISPLAY) {
+       if (req_config_methods & WPS_CONFIG_DISPLAY) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR
                        " accepted to show a PIN on display", MAC2STR(sa));
                dev->flags |= P2P_DEV_PD_PEER_DISPLAY;