]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Fix nl_mgmt handling in partial error case
authorJouni Malinen <j@w1.fi>
Tue, 31 Dec 2013 08:17:53 +0000 (10:17 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 31 Dec 2013 13:45:18 +0000 (15:45 +0200)
If Action frame registration in nl80211_mgmt_subscribe_non_ap() failed
for any frame type, the previous implementation skipped
nl80211_mgmt_handle_register_eloop() call. This is not desirable since
none of the Action frame types could be received and even worse, the
following nl80211_destroy_eloop_handle() call for nl_mgmt would likely
result in crashing the process due to the ELOOP_SOCKET_INVALID XOR
operation. This could be triggered at least in a P2P group interface
startup failure case.

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

src/drivers/driver_nl80211.c

index 58d6fd620874dfd1bb2556eadabe8201cf134573..30b04976a0e6f4faa0089dc1b1f3e9e3dc7280a4 100644 (file)
@@ -4050,6 +4050,7 @@ static int nl80211_register_action_frame(struct i802_bss *bss,
 static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
 {
        struct wpa_driver_nl80211_data *drv = bss->drv;
+       int ret = 0;
 
        if (nl80211_alloc_mgmt_handle(bss))
                return -1;
@@ -4066,65 +4067,65 @@ static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
 #ifdef CONFIG_INTERWORKING
        /* QoS Map Configure */
        if (nl80211_register_action_frame(bss, (u8 *) "\x01\x04", 2) < 0)
-               return -1;
+               ret = -1;
 #endif /* CONFIG_INTERWORKING */
 #if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING)
        /* GAS Initial Request */
        if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0a", 2) < 0)
-               return -1;
+               ret = -1;
        /* GAS Initial Response */
        if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0b", 2) < 0)
-               return -1;
+               ret = -1;
        /* GAS Comeback Request */
        if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0c", 2) < 0)
-               return -1;
+               ret = -1;
        /* GAS Comeback Response */
        if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0d", 2) < 0)
-               return -1;
+               ret = -1;
 #endif /* CONFIG_P2P || CONFIG_INTERWORKING */
 #ifdef CONFIG_P2P
        /* P2P Public Action */
        if (nl80211_register_action_frame(bss,
                                          (u8 *) "\x04\x09\x50\x6f\x9a\x09",
                                          6) < 0)
-               return -1;
+               ret = -1;
        /* P2P Action */
        if (nl80211_register_action_frame(bss,
                                          (u8 *) "\x7f\x50\x6f\x9a\x09",
                                          5) < 0)
-               return -1;
+               ret = -1;
 #endif /* CONFIG_P2P */
 #ifdef CONFIG_IEEE80211W
        /* SA Query Response */
        if (nl80211_register_action_frame(bss, (u8 *) "\x08\x01", 2) < 0)
-               return -1;
+               ret = -1;
 #endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_TDLS
        if ((drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)) {
                /* TDLS Discovery Response */
                if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0e", 2) <
                    0)
-                       return -1;
+                       ret = -1;
        }
 #endif /* CONFIG_TDLS */
 
        /* FT Action frames */
        if (nl80211_register_action_frame(bss, (u8 *) "\x06", 1) < 0)
-               return -1;
+               ret = -1;
        else
                drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
                        WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
 
        /* WNM - BSS Transition Management Request */
        if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x07", 2) < 0)
-               return -1;
+               ret = -1;
        /* WNM-Sleep Mode Response */
        if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x11", 2) < 0)
-               return -1;
+               ret = -1;
 
        nl80211_mgmt_handle_register_eloop(bss);
 
-       return 0;
+       return ret;
 }