wifi: Stack based crash risk fixed
[framework/connectivity/connman.git] / gsupplicant / supplicant.c
index 42f4920..cbbe95c 100644 (file)
@@ -406,6 +406,7 @@ static void remove_interface(gpointer data)
        callback_interface_removed(interface);
 
        g_free(interface->path);
+       g_free(interface->network_path);
        g_free(interface->ifname);
        g_free(interface->driver);
        g_free(interface->bridge);
@@ -422,6 +423,7 @@ static void remove_network(gpointer data)
 
        g_hash_table_destroy(network->config_table);
 
+       g_free(network->path);
        g_free(network->group);
        g_free(network->name);
        g_free(network);
@@ -1137,7 +1139,8 @@ static void bss_property(const char *key, DBusMessageIter *iter,
                                key, dbus_message_iter_get_arg_type(iter));
 }
 
-static void interface_bss_added(DBusMessageIter *iter, void *user_data)
+static struct g_supplicant_bss *interface_bss_added(DBusMessageIter *iter,
+                                                       void *user_data)
 {
        GSupplicantInterface *interface = user_data;
        GSupplicantNetwork *network;
@@ -1148,10 +1151,10 @@ static void interface_bss_added(DBusMessageIter *iter, void *user_data)
 
        dbus_message_iter_get_basic(iter, &path);
        if (path == NULL)
-               return;
+               return NULL;
 
        if (g_strcmp0(path, "/") == 0)
-               return;
+               return NULL;
 
        SUPPLICANT_DBG("%s", path);
 
@@ -1159,24 +1162,51 @@ static void interface_bss_added(DBusMessageIter *iter, void *user_data)
        if (network != NULL) {
                bss = g_hash_table_lookup(network->bss_table, path);
                if (bss != NULL)
-                       return;
+                       return NULL;
        }
 
        bss = g_try_new0(struct g_supplicant_bss, 1);
        if (bss == NULL)
-               return;
+               return NULL;
 
        bss->interface = interface;
        bss->path = g_strdup(path);
 
+       return bss;
+}
+
+static void interface_bss_added_with_keys(DBusMessageIter *iter,
+                                               void *user_data)
+{
+       struct g_supplicant_bss *bss;
+
+       SUPPLICANT_DBG("");
+
+       bss = interface_bss_added(iter, user_data);
+       if (bss == NULL)
+               return;
+
        dbus_message_iter_next(iter);
-       if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
-               supplicant_dbus_property_foreach(iter, bss_property, bss);
-               bss_property(NULL, NULL, bss);
+
+       if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_INVALID)
                return;
-       }
 
-       supplicant_dbus_property_get_all(path,
+       supplicant_dbus_property_foreach(iter, bss_property, bss);
+       bss_property(NULL, NULL, bss);
+}
+
+static void interface_bss_added_without_keys(DBusMessageIter *iter,
+                                               void *user_data)
+{
+       struct g_supplicant_bss *bss;
+
+       SUPPLICANT_DBG("");
+
+       bss = interface_bss_added(iter, user_data);
+       if (bss == NULL)
+               return;
+
+       supplicant_dbus_property_get_all(bss->path,
                                        SUPPLICANT_INTERFACE ".BSS",
                                                        bss_property, bss);
 }
@@ -1270,26 +1300,32 @@ static void interface_property(const char *key, DBusMessageIter *iter,
                const char *str = NULL;
 
                dbus_message_iter_get_basic(iter, &str);
-               if (str != NULL)
+               if (str != NULL) {
+                       g_free(interface->ifname);
                        interface->ifname = g_strdup(str);
+               }
        } else if (g_strcmp0(key, "Driver") == 0) {
                const char *str = NULL;
 
                dbus_message_iter_get_basic(iter, &str);
-               if (str != NULL)
+               if (str != NULL) {
+                       g_free(interface->driver);
                        interface->driver = g_strdup(str);
+               }
        } else if (g_strcmp0(key, "BridgeIfname") == 0) {
                const char *str = NULL;
 
                dbus_message_iter_get_basic(iter, &str);
-               if (str != NULL)
+               if (str != NULL) {
+                       g_free(interface->bridge);
                        interface->bridge = g_strdup(str);
+               }
        } else if (g_strcmp0(key, "CurrentBSS") == 0) {
-               interface_bss_added(iter, interface);
+               interface_bss_added_without_keys(iter, interface);
        } else if (g_strcmp0(key, "CurrentNetwork") == 0) {
                interface_network_added(iter, interface);
        } else if (g_strcmp0(key, "BSSs") == 0) {
-               supplicant_dbus_array_foreach(iter, interface_bss_added,
+               supplicant_dbus_array_foreach(iter, interface_bss_added_without_keys,
                                                                interface);
        } else if (g_strcmp0(key, "Blobs") == 0) {
                /* Nothing */
@@ -1585,7 +1621,7 @@ static void signal_bss_added(const char *path, DBusMessageIter *iter)
        if (interface == NULL)
                return;
 
-       interface_bss_added(iter, interface);
+       interface_bss_added_with_keys(iter, interface);
 }
 
 static void signal_bss_removed(const char *path, DBusMessageIter *iter)
@@ -1984,12 +2020,15 @@ static void interface_remove_result(const char *error,
                goto done;
        }
 
-       g_hash_table_remove(interface_table, data->interface->path);
+       /*
+        * The gsupplicant interface is already freed by the InterfaceRemoved
+        * signal callback. Simply invoke the interface_data callback.
+        */
        err = 0;
 
 done:
        if (data->callback != NULL)
-               data->callback(err, data->interface, data->user_data);
+               data->callback(err, NULL, data->user_data);
 
        dbus_free(data);
 }
@@ -2110,6 +2149,7 @@ static void interface_select_network_result(const char *error,
 
        SUPPLICANT_DBG("");
 
+       g_free(data->ssid);
        dbus_free(data);
 }
 
@@ -2152,6 +2192,7 @@ static void interface_add_network_result(const char *error,
 error:
        g_free(interface->network_path);
        interface->network_path = NULL;
+       g_free(data->ssid);
        g_free(data);
 }
 
@@ -2301,7 +2342,7 @@ static void add_network_security_peap(DBusMessageIter *dict,
 
        }
 
-       phase2_auth = g_strdup_printf("\"auth=%s\"", ssid->phase2_auth);
+       phase2_auth = g_strdup_printf("auth=%s", ssid->phase2_auth);
 
        supplicant_dbus_dict_append_basic(dict, "password",
                                                DBUS_TYPE_STRING,
@@ -2313,7 +2354,7 @@ static void add_network_security_peap(DBusMessageIter *dict,
 
        supplicant_dbus_dict_append_basic(dict, "phase2",
                                                DBUS_TYPE_STRING,
-                                               &ssid->phase2_auth);
+                                               &phase2_auth);
 
        g_free(phase2_auth);
 }
@@ -2628,6 +2669,9 @@ void g_supplicant_unregister(const GSupplicantCallbacks *callbacks)
                bss_mapping = NULL;
        }
 
+       if (system_available == TRUE)
+               callback_system_killed();
+
        if (interface_table != NULL) {
                g_hash_table_foreach(interface_table,   
                                        unregister_remove_interface, NULL);
@@ -2635,9 +2679,6 @@ void g_supplicant_unregister(const GSupplicantCallbacks *callbacks)
                interface_table = NULL;
        }
 
-       if (system_available == TRUE)
-               callback_system_killed();
-
        if (connection != NULL) {
                dbus_connection_unref(connection);
                connection = NULL;