diff --git a/attrib/gatt.c b/attrib/gatt.c
index 1816234..1db34be 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
if (dp->ref > 0)
return;
- g_slist_free(dp->primaries);
+ g_slist_free_full(dp->primaries, g_free);
g_attrib_unref(dp->attrib);
g_free(dp);
}
diff --git a/src/device.c b/src/device.c
index 60820b7..f72a72b 100644
--- a/src/device.c
+++ b/src/device.c
g_slist_free_full(device->primaries, g_free);
device->primaries = NULL;
- device_register_primaries(device, g_slist_copy(services), -1);
+ device_register_primaries(device, services, -1);
device_probe_profiles(device, req->profiles_added);
search->current = search->current->next;
if (search->current == NULL) {
register_all_services(search->req, search->services);
+ search->services = NULL;
goto complete;
}
return;
complete:
- g_slist_free(search->services);
+ g_slist_free_full(search->services, g_free);
g_free(search);
}
struct btd_device *device = req->device;
struct included_search *search;
struct gatt_primary *prim;
+ GSList *l;
DBG("service count %u", g_slist_length(services));
search = g_new0(struct included_search, 1);
search->req = req;
- search->services = g_slist_copy(services);
+
+ /* We have to completely duplicate the data in order to have a
+ * clearly defined responsibility of freeing regardless of
+ * failure or success. Otherwise memory leaks are inevitable.
+ */
+ for (l = services; l; l = g_slist_next(l)) {
+ struct gatt_primary *dup;
+
+ dup = g_memdup(l->data, sizeof(struct gatt_primary));
+
+ search->services = g_slist_append(search->services, dup);
+ }
+
search->current = search->services;
prim = search->current->data;