Fix invalid read 17/196217/1
authorSeungyoun Ju <sy39.ju@samsung.com>
Fri, 14 Dec 2018 06:32:25 +0000 (15:32 +0900)
committerSeungyoun Ju <sy39.ju@samsung.com>
Wed, 26 Dec 2018 09:12:36 +0000 (18:12 +0900)
[Problem] There is invalid read report from valgrind
[Cause & Measure] The node was accessed after it was freed. This patch
 frees current node after moving to the next node so that invalid read
 issue has been resolved.

Change-Id: I15eae8c16c8f215aee30fd33ac8f3aadea73b4eb

bt-api/bt-gatt-service.c

index 22c8ea4..f56447b 100644 (file)
@@ -2495,33 +2495,33 @@ BT_EXPORT_API int bluetooth_gatt_register_application(void)
 BT_EXPORT_API int bluetooth_gatt_delete_services(void)
 {
        GSList *l;
-       int error = BLUETOOTH_ERROR_NONE;
-       l = gatt_services;
-
-       if (l != NULL) {
-               for (l = gatt_services; l != NULL; l = l->next) {
-                       struct gatt_service_info *info = l->data;
-                       BT_DBG("svc_path is %s", info->serv_path);
-                       if (bluetooth_gatt_unregister_service(info->serv_path)
-                                       != BLUETOOTH_ERROR_NONE) {
-                               error = BLUETOOTH_ERROR_INTERNAL;
-                               BT_ERR("Error in removing service %s \n",
-                                                info->serv_path);
-                       }
+       int ret = BLUETOOTH_ERROR_NONE;
+
+       if (gatt_services == NULL) {
+               BT_DBG("There are no registered services");
+               serv_id = 1;
+               return ret;
+       }
+
+       for (l = gatt_services; l != NULL; ) {
+               struct gatt_service_info *info = l->data;
+
+               // In bluetooth_gatt_unregister_service, current node will be removed.
+               // Go forward to next node before calling bluetooth_gatt_unregister_service.
+               l = l->next;
+               BT_DBG("svc_path is %s", info->serv_path);
+               if (bluetooth_gatt_unregister_service(info->serv_path) != BLUETOOTH_ERROR_NONE) {
+                       ret = BLUETOOTH_ERROR_INTERNAL;
+                       BT_ERR("Error in removing service %s", info->serv_path);
                }
-               BT_DBG(" All services removed successfully.\n ");
-       } else {
-               BT_DBG(" There are no registered services.\n ");
        }
+       BT_INFO("All services are removed : %d", ret);
 
        g_slist_free(gatt_services);
        gatt_services = NULL;
        serv_id = 1;
 
-       if (error != BLUETOOTH_ERROR_NONE)
-               return error;
-
-       return BLUETOOTH_ERROR_NONE;
+       return ret;
 }
 
 BT_EXPORT_API int bluetooth_gatt_update_characteristic(
@@ -2667,9 +2667,48 @@ static void __bt_gatt_free_service_info(struct gatt_service_info *svc_info)
        g_free(svc_info);
 }
 
+static void __desc_info_free(gpointer data, gpointer user_data)
+{
+       struct gatt_desc_info *desc_info = data;
+       int *err = user_data;
+       int ret;
+
+       if (desc_info == NULL)
+               return;
+
+       ret = g_dbus_connection_unregister_object(g_conn, desc_info->desc_id);
+       if (ret) {
+               __bt_gatt_emit_interface_removed(desc_info->desc_path, GATT_DESC_INTERFACE);
+       } else {
+               *err = BLUETOOTH_ERROR_INTERNAL;
+       }
+       __bt_gatt_free_descriptor_info(desc_info);
+}
+
+static void __char_info_free(gpointer data, gpointer user_data)
+{
+       struct gatt_char_info *char_info = data;
+       int *err = user_data;
+       int ret;
+
+       if (char_info == NULL)
+               return;
+
+       g_slist_foreach(char_info->desc_data, __desc_info_free, user_data);
+       g_slist_free(char_info->desc_data);
+       char_info->desc_data = NULL;
+
+       ret = g_dbus_connection_unregister_object(g_conn, char_info->char_id);
+       if (ret) {
+               __bt_gatt_emit_interface_removed(char_info->char_path, GATT_CHAR_INTERFACE);
+       } else {
+               *err = BLUETOOTH_ERROR_INTERNAL;
+       }
+       __bt_gatt_free_characteristic_info(char_info);
+}
+
 BT_EXPORT_API int bluetooth_gatt_unregister_service(const char *svc_path)
 {
-       GSList *l, *l1;
        struct gatt_service_info *svc_info;
        gboolean ret;
        int err = BLUETOOTH_ERROR_NONE;
@@ -2688,50 +2727,7 @@ BT_EXPORT_API int bluetooth_gatt_unregister_service(const char *svc_path)
                return err;
        }
 
-       for (l = svc_info->char_data; l != NULL; l = l->next) {
-               struct gatt_char_info *char_info = l->data;
-
-               if (char_info == NULL)
-                       break;
-
-               for (l1 = char_info->desc_data; l1 != NULL; l1 = l1->next) {
-                       struct gatt_desc_info *desc_info = l1->data;
-
-                       if (desc_info == NULL)
-                               break;
-
-                       ret = g_dbus_connection_unregister_object(g_conn,
-                                               desc_info->desc_id);
-                       if (ret) {
-                               __bt_gatt_emit_interface_removed(
-                                               desc_info->desc_path,
-                                               GATT_DESC_INTERFACE);
-                       } else {
-                               err = BLUETOOTH_ERROR_INTERNAL;
-                       }
-
-                       /* list remove & free */
-                       char_info->desc_data = g_slist_remove(char_info->desc_data, desc_info);
-                       __bt_gatt_free_descriptor_info(desc_info);
-               }
-
-               g_slist_free(char_info->desc_data);
-               char_info->desc_data = NULL;
-
-               ret = g_dbus_connection_unregister_object(g_conn,
-                                       char_info->char_id);
-               if (ret) {
-                       __bt_gatt_emit_interface_removed(char_info->char_path,
-                                               GATT_CHAR_INTERFACE);
-               } else {
-                       err = BLUETOOTH_ERROR_INTERNAL;
-               }
-
-               /* list remove & free */
-               svc_info->char_data = g_slist_remove(svc_info->char_data, char_info);
-               __bt_gatt_free_characteristic_info(char_info);
-       }
-
+       g_slist_foreach(svc_info->char_data, __char_info_free, &err);
        g_slist_free(svc_info->char_data);
        svc_info->char_data = NULL;