Ignore async dbus method call reply when G_IO_ERROR_CANCELLED is returned 72/266772/3 accepted/tizen/unified/20211129.120823 submit/tizen/20211125.124313 submit/tizen/20211126.045758
authorNishant Chaprana <n.chaprana@samsung.com>
Thu, 18 Nov 2021 11:02:22 +0000 (16:32 +0530)
committerNishant Chaprana <n.chaprana@samsung.com>
Tue, 23 Nov 2021 05:13:55 +0000 (10:43 +0530)
In below scenario there are chances of dangling pointer access.
1. wifi_manager_initialize()

2. wifi_scan() or any other API which makes async dbus method call.
   --> GDBUS increases gdbus connection ref count.

3. wifi_manager_deinitialize()
   --> we cancel all method calls and unref gdbus connection and assign NULL to it.

4. Dbus reply recieved on default thread.
   --> Because gdbus connection is not freed by gdbus, callback comes to us.

5. G_IO_ERROR_CANCELLED returned in g_dbus_connection_call_finish()
   --> Invalid memory access when network_info is derefered for sending callback.

Change-Id: I592f33f115aa6091890a530b1e2daaec88a45d81
Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
src/network_dbus.c

index 4f930df872de9f91e0372a206d8a511556900370..c5545dd401c4d37eedc7948eaf7075a61f006623 100644 (file)
@@ -86,7 +86,7 @@ static int __net_error_string_to_enum(const char *error)
        else if (NULL != strstr(error, "NoProfile"))
                return NET_ERR_NO_PROFILE;
        else if (NULL != strstr(error, "FailTdlsDiscover"))
-                       return NET_ERR_FAIL_TDLS_DISCOVER;
+               return NET_ERR_FAIL_TDLS_DISCOVER;
 
        return NET_ERR_UNKNOWN;
 }
@@ -278,6 +278,13 @@ static void __net_open_connection_reply(GObject *source_object, GAsyncResult *re
 
        if (error != NULL) {
                Error = __net_error_string_to_enum(error->message);
+               if (error->code == G_IO_ERROR_CANCELLED) {
+                       WIFI_LOG(WIFI_INFO, "Ignore open connection reply, as operation is cancelled");
+                       g_error_free(error);
+                       __NETWORK_FUNC_EXIT__;
+                       return;
+               }
+
                g_error_free(error);
        }
 
@@ -390,8 +397,8 @@ static void __net_scan_reply(GObject *source_object, GAsyncResult *res, gpointer
        net_event_info_s *event_data;
 
        network_info_s *network_info = (network_info_s *)user_data;
-       network_request_table_s *request_table = network_info->request_table;
-       network_request_table_s *bssid_scan_info = &request_table[NETWORK_REQUEST_TYPE_BSSID_SCAN];
+       network_request_table_s *request_table;
+       network_request_table_s *bssid_scan_info;
 
        event_data = g_try_malloc0(sizeof(net_event_info_s));
        if (event_data == NULL) {
@@ -406,12 +413,22 @@ static void __net_scan_reply(GObject *source_object, GAsyncResult *res, gpointer
                WIFI_LOG(WIFI_ERROR, "Scan failed. Error [%s]",
                                error->message);
                Error = __net_error_string_to_enum(error->message);
+               if (error->code == G_IO_ERROR_CANCELLED) {
+                       WIFI_LOG(WIFI_INFO, "Ignore scan reply, as operation is cancelled");
+                       g_error_free(error);
+                       __NETWORK_FUNC_EXIT__;
+                       return;
+               }
+
                g_error_free(error);
        }
 
        if (reply)
                g_variant_unref(reply);
 
+       request_table = network_info->request_table;
+       bssid_scan_info = &request_table[NETWORK_REQUEST_TYPE_BSSID_SCAN];
+
        /* Show scan list even if device is in association state */
        if (bssid_scan_info->flag == TRUE && Error == NET_ERR_FAIL_DEVICE_BUSY) {
                memset(&request_table[NETWORK_REQUEST_TYPE_BSSID_SCAN],
@@ -486,9 +503,8 @@ static void __net_close_connection_reply(GObject *source_object, GAsyncResult *r
        GVariant *reply;
        net_event_info_s *event_data = NULL;
        network_info_s *network_info = (network_info_s *)user_data;
-       network_request_table_s *request_table = network_info->request_table;
-       network_request_table_s *close_info =
-                       &request_table[NETWORK_REQUEST_TYPE_CLOSE_CONNECTION];
+       network_request_table_s *request_table;
+       network_request_table_s *close_info;
 
        WIFI_LOG(WIFI_INFO, "__net_close_connection_reply() called");
 
@@ -500,8 +516,16 @@ static void __net_close_connection_reply(GObject *source_object, GAsyncResult *r
 
        conn = G_DBUS_CONNECTION(source_object);
        reply = g_dbus_connection_call_finish(conn, res, &error);
+
        if (error != NULL) {
                Error = __net_error_string_to_enum(error->message);
+               if (error->code == G_IO_ERROR_CANCELLED) {
+                       WIFI_LOG(WIFI_INFO, "Ignore close connection reply, as operation is cancelled");
+                       g_error_free(error);
+                       __NETWORK_FUNC_EXIT__;
+                       return;
+               }
+
                g_error_free(error);
        }
 
@@ -513,6 +537,9 @@ static void __net_close_connection_reply(GObject *source_object, GAsyncResult *r
 
        WIFI_LOG(WIFI_ERROR, "Connection close failed[%d]", Error);
 
+       request_table = network_info->request_table;
+       close_info = &request_table[NETWORK_REQUEST_TYPE_CLOSE_CONNECTION];
+
        if (close_info->flag == TRUE) {
                g_strlcpy(event_data->ProfileName, close_info->ProfileName,
                                NET_PROFILE_NAME_LEN_MAX + 1);
@@ -550,7 +577,7 @@ static void __net_wifi_power_reply(GObject *source_object, GAsyncResult *res, gp
        net_event_info_s *event_data = NULL;
        GVariant *reply;
        network_info_s *network_info = (network_info_s *)user_data;
-       network_request_table_s *request_table = network_info->request_table;
+       network_request_table_s *request_table;
 
        WIFI_LOG(WIFI_INFO, "__net_wifi_power_reply() called");
 
@@ -562,14 +589,24 @@ static void __net_wifi_power_reply(GObject *source_object, GAsyncResult *res, gp
 
        conn = G_DBUS_CONNECTION(source_object);
        reply = g_dbus_connection_call_finish(conn, res, &error);
+
        if (error != NULL) {
                Error = __net_netconfig_error_string_to_enum(error->message);
+               if (error->code == G_IO_ERROR_CANCELLED) {
+                       WIFI_LOG(WIFI_INFO, "Ignore wifi power reply, as operation is cancelled");
+                       g_error_free(error);
+                       __NETWORK_FUNC_EXIT__;
+                       return;
+               }
+
                g_error_free(error);
        }
 
        if (reply)
                g_variant_unref(reply);
 
+       request_table = network_info->request_table;
+
        if (Error != NET_ERR_NONE) {
                WIFI_LOG(WIFI_ERROR, "Wi-Fi power operation failed. Error [%d]", Error);
 
@@ -612,7 +649,7 @@ static void __net_bssid_scan_wifi_reply(GObject *source_object, GAsyncResult *re
        net_err_e Error = NET_ERR_NONE;
        net_event_info_s *event_data = NULL;
        network_info_s *network_info = (network_info_s *)user_data;
-       network_request_table_s *request_table = network_info->request_table;
+       network_request_table_s *request_table;
 
        event_data = g_try_malloc0(sizeof(net_event_info_s));
        if (event_data == NULL) {
@@ -622,14 +659,24 @@ static void __net_bssid_scan_wifi_reply(GObject *source_object, GAsyncResult *re
 
        conn = G_DBUS_CONNECTION(source_object);
        reply = g_dbus_connection_call_finish(conn, res, &error);
+
        if (error != NULL) {
                Error = __net_netconfig_error_string_to_enum(error->message);
+               if (error->code == G_IO_ERROR_CANCELLED) {
+                       WIFI_LOG(WIFI_INFO, "Ignore bssid scan reply, as operation is cancelled");
+                       g_error_free(error);
+                       __NETWORK_FUNC_EXIT__;
+                       return;
+               }
+
                g_error_free(error);
        }
 
        if (reply)
                g_variant_unref(reply);
 
+       request_table = network_info->request_table;
+
        if (Error != NET_ERR_NONE) {
                WIFI_LOG(WIFI_ERROR, "bssid scan failed[%d]", Error);
 
@@ -666,7 +713,7 @@ static void __net_netlink_scan_wifi_reply(GObject *source_object, GAsyncResult *
        net_err_e Error = NET_ERR_NONE;
        net_event_info_s *event_data = NULL;
        network_info_s *network_info = (network_info_s *)user_data;
-       network_request_table_s *request_table = network_info->request_table;
+       network_request_table_s *request_table;
 
        event_data = g_try_malloc0(sizeof(net_event_info_s));
        if (event_data == NULL) {
@@ -676,14 +723,24 @@ static void __net_netlink_scan_wifi_reply(GObject *source_object, GAsyncResult *
 
        conn = G_DBUS_CONNECTION(source_object);
        reply = g_dbus_connection_call_finish(conn, res, &error);
+
        if (error != NULL) {
                Error = __net_netconfig_error_string_to_enum(error->message);
+               if (error->code == G_IO_ERROR_CANCELLED) {
+                       WIFI_LOG(WIFI_INFO, "Ignore netlink scan reply, as operation is cancelled");
+                       g_error_free(error);
+                       __NETWORK_FUNC_EXIT__;
+                       return;
+               }
+
                g_error_free(error);
        }
 
        if (reply)
                g_variant_unref(reply);
 
+       request_table = network_info->request_table;
+
        if (Error != NET_ERR_NONE) {
                WIFI_LOG(WIFI_ERROR, "netlink scan failed[%d]", Error);
 
@@ -722,8 +779,16 @@ static void __net_set_passpoint_reply(GObject *source_object, GAsyncResult *res,
 
        conn = G_DBUS_CONNECTION(source_object);
        reply = g_dbus_connection_call_finish(conn, res, &error);
+
        if (error != NULL) {
                Error = __net_netconfig_error_string_to_enum(error->message);
+               if (error->code == G_IO_ERROR_CANCELLED) {
+                       WIFI_LOG(WIFI_INFO, "Ignore set passpoint reply, as operation is cancelled");
+                       g_error_free(error);
+                       __NETWORK_FUNC_EXIT__;
+                       return;
+               }
+
                g_error_free(error);
        }
 
@@ -1993,7 +2058,7 @@ static void __net_specific_scan_request_reply(GObject *source_object, GAsyncResu
        net_event_info_s *event_data = NULL;
        GVariant *reply;
        network_info_s *network_info = (network_info_s *)user_data;
-       network_request_table_s *request_table = network_info->request_table;
+       network_request_table_s *request_table;
 
        event_data = g_try_malloc0(sizeof(net_event_info_s));
        if (event_data == NULL) {
@@ -2003,16 +2068,26 @@ static void __net_specific_scan_request_reply(GObject *source_object, GAsyncResu
 
        conn = G_DBUS_CONNECTION(source_object);
        reply = g_dbus_connection_call_finish(conn, res, &error);
+
        if (error != NULL) {
                WIFI_LOG(WIFI_ERROR, "Scan failed. Error [%s]",
                                error->message);
                Error = __net_error_string_to_enum(error->message);
+               if (error->code == G_IO_ERROR_CANCELLED) {
+                       WIFI_LOG(WIFI_INFO, "Ignore specific scan request reply, as operation is cancelled");
+                       g_error_free(error);
+                       __NETWORK_FUNC_EXIT__;
+                       return;
+               }
+
                g_error_free(error);
        }
 
        if (reply)
                g_variant_unref(reply);
 
+       request_table = network_info->request_table;
+
        if (Error == NET_ERR_IN_PROGRESS) {
                /* should retry scan after receiving scan result */
                if (request_table[NETWORK_REQUEST_TYPE_SPECIFIC_SCAN].flag == TRUE) {
@@ -2549,6 +2624,13 @@ static void __net_wps_cancel_reply(GObject *source_object,
 
        if (error != NULL) {
                WIFI_LOG(WIFI_ERROR, "error msg - [%s]", error->message);
+               if (error->code == G_IO_ERROR_CANCELLED) {
+                       WIFI_LOG(WIFI_INFO, "Ignore wps cancel reply, as operation is cancelled");
+                       g_error_free(error);
+                       __NETWORK_FUNC_EXIT__;
+                       return;
+               }
+
                g_error_free(error);
        }
 
@@ -2590,8 +2672,8 @@ static void __net_wps_connect_wifi_reply(GObject *source_object,
        net_event_info_s *event_data = NULL;
        net_err_e Error = NET_ERR_NONE;
        network_info_s *network_info = (network_info_s *)user_data;
-       network_request_table_s *request_table = network_info->request_table;
-       network_request_table_s *wps_info = &request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS];
+       network_request_table_s *request_table;
+       network_request_table_s *wps_info;
 
        event_data = g_try_malloc0(sizeof(net_event_info_s));
        if (event_data == NULL) {
@@ -2605,6 +2687,13 @@ static void __net_wps_connect_wifi_reply(GObject *source_object,
        if (error != NULL) {
                WIFI_LOG(WIFI_INFO, "error msg - [%s]", error->message);
                Error = __net_error_string_to_enum(error->message);
+               if (error->code == G_IO_ERROR_CANCELLED) {
+                       WIFI_LOG(WIFI_INFO, "Ignore wps connect reply, as operation is cancelled");
+                       g_error_free(error);
+                       __NETWORK_FUNC_EXIT__;
+                       return;
+               }
+
                g_error_free(error);
        } else
                WIFI_LOG(WIFI_INFO, "error msg is NULL");
@@ -2620,6 +2709,9 @@ static void __net_wps_connect_wifi_reply(GObject *source_object,
 
        WIFI_LOG(WIFI_ERROR, "Connection open failed. Error [%d]", Error);
 
+       request_table = network_info->request_table;
+       wps_info = &request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS];
+
        memset(wps_info, 0, sizeof(network_request_table_s));
 
        event_data->Error = Error;
@@ -3893,7 +3985,7 @@ static void __net_multi_scan_request_reply(GObject *source_object, GAsyncResult
        net_err_e Error = NET_ERR_NONE;
        net_event_info_s *event_data = NULL;
        network_info_s *network_info = (network_info_s *)user_data;
-       network_request_table_s *request_table = network_info->request_table;
+       network_request_table_s *request_table;
 
        event_data = g_try_malloc0(sizeof(net_event_info_s));
        if (event_data == NULL) {
@@ -3903,16 +3995,26 @@ static void __net_multi_scan_request_reply(GObject *source_object, GAsyncResult
 
        conn = G_DBUS_CONNECTION(source_object);
        reply = g_dbus_connection_call_finish(conn, res, &error);
+
        if (error != NULL) {
                WIFI_LOG(WIFI_ERROR, "Scan failed. Error [%s]",
                                error->message);
                Error = __net_error_string_to_enum(error->message);
+               if (error->code == G_IO_ERROR_CANCELLED) {
+                       WIFI_LOG(WIFI_INFO, "Ignore multi scan request reply, as operation is cancelled");
+                       g_error_free(error);
+                       __NETWORK_FUNC_EXIT__;
+                       return;
+               }
+
                g_error_free(error);
        }
 
        if (reply)
                g_variant_unref(reply);
 
+       request_table = network_info->request_table;
+
        if (Error == NET_ERR_IN_PROGRESS) {
                /* should retry scan after receiving scan result */
                if (request_table[NETWORK_REQUEST_TYPE_MULTI_SCAN].flag == TRUE) {