If a wifi struct is deallocated during a pending D-Bus method call,
wifi_tethering_info may contain a pointer to the freed
memory. Reworked the code so that pointers to deallocated wifi structs
are cleared.
---
plugins/wifi.c | 47 +++++++++++++++++++++++++++++++++--------------
1 file changed, 33 insertions(+), 14 deletions(-)
diff --git a/plugins/wifi.c b/plugins/wifi.c
index d18dc6c..ab23bb8 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -128,6 +128,15 @@ struct wifi_data {
int servicing;
};
+struct wifi_tethering_info {
+ struct wifi_data *wifi;
+ struct connman_technology *technology;
+ char *ifname;
+ GSupplicantSSID *ssid;
+};
+
+static GSList *tethering_info_list = NULL;
+
static GList *iface_list = NULL;
static GList *pending_wifi_device = NULL;
@@ -671,6 +680,7 @@ static void check_p2p_technology(void)
static void wifi_remove(struct connman_device *device)
{
struct wifi_data *wifi = connman_device_get_data(device);
+ GSList *t;
DBG("device %p wifi %p", device, wifi);
@@ -713,6 +723,12 @@ static void wifi_remove(struct connman_device *device)
g_free(wifi->autoscan);
g_free(wifi->identifier);
g_free(wifi);
+
+ for (t = tethering_info_list; t; t = t->next) {
+ struct wifi_tethering_info *info = t->data;
+ if (info->wifi == wifi)
+ info->wifi = NULL;
+ }
}
static bool is_duplicate(GSList *list, gchar *ssid, int ssid_len)
@@ -2678,13 +2694,6 @@ static void tech_remove(struct connman_technology
*technology)
wifi_technology = NULL;
}
-struct wifi_tethering_info {
- struct wifi_data *wifi;
- struct connman_technology *technology;
- char *ifname;
- GSupplicantSSID *ssid;
-};
-
static GSupplicantSSID *ssid_ap_init(const char *ssid, const char *passphrase)
{
GSupplicantSSID *ap;
@@ -2719,16 +2728,20 @@ static void ap_start_callback(int result,
GSupplicantInterface *interface,
struct wifi_tethering_info *info = user_data;
DBG("result %d index %d bridge %s",
- result, info->wifi->index, info->wifi->bridge);
+ result,
+ info->wifi ? info->wifi->index : -1,
+ info->wifi ? info->wifi->bridge : "");
- if (result < 0) {
- connman_inet_remove_from_bridge(info->wifi->index,
+ if (result < 0 || info->wifi == NULL) {
+ if (info->wifi)
+ connman_inet_remove_from_bridge(info->wifi->index,
info->wifi->bridge);
connman_technology_tethering_notify(info->technology, false);
}
g_free(info->ifname);
g_free(info);
+ tethering_info_list = g_slist_remove(tethering_info_list, info);
}
static void ap_create_callback(int result,
@@ -2740,14 +2753,16 @@ static void ap_create_callback(int result,
DBG("result %d ifname %s", result,
g_supplicant_interface_get_ifname(interface));
- if (result < 0) {
- connman_inet_remove_from_bridge(info->wifi->index,
+ if (result < 0 || info->wifi == NULL) {
+ if (info->wifi)
+ connman_inet_remove_from_bridge(info->wifi->index,
info->wifi->bridge);
connman_technology_tethering_notify(info->technology, false);
g_free(info->ifname);
g_free(info->ssid);
g_free(info);
+ tethering_info_list = g_slist_remove(tethering_info_list, info);
return;
}
@@ -2770,12 +2785,14 @@ static void sta_remove_callback(int result,
DBG("ifname %s result %d ", info->ifname, result);
- if (result < 0) {
- info->wifi->tethering = true;
+ if (result < 0 || info->wifi == NULL) {
+ if (info->wifi)
+ info->wifi->tethering = true;
g_free(info->ifname);
g_free(info->ssid);
g_free(info);
+ tethering_info_list = g_slist_remove(tethering_info_list, info);
return;
}
@@ -2857,6 +2874,8 @@ static int tech_set_tethering(struct connman_technology
*technology,
info->wifi->tethering = true;
+ tethering_info_list = g_slist_prepend(tethering_info_list,
info);
+
err = g_supplicant_interface_remove(interface,
sta_remove_callback,
info);
--
1.9.1
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman