From 1cfa2d1e20d9a55906580c5e3f82c3c49d2516e5 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 4 Aug 2022 15:16:44 -0700 Subject: [PATCH] pkg: prevent circular ownership Otherwise in a case where A references B, and B references A, A and B will have mutual ownership of each other and prevent each other from being free'd. --- libpkgconf/pkg.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libpkgconf/pkg.c b/libpkgconf/pkg.c index 2555e59..5f2f603 100644 --- a/libpkgconf/pkg.c +++ b/libpkgconf/pkg.c @@ -1445,9 +1445,9 @@ pkgconf_pkg_walk_list(pkgconf_client_t *client, unsigned int skip_flags) { unsigned int eflags = PKGCONF_PKG_ERRF_OK; - pkgconf_node_t *node; + pkgconf_node_t *node, *next; - PKGCONF_FOREACH_LIST_ENTRY(deplist->head, node) + PKGCONF_FOREACH_LIST_ENTRY_SAFE(deplist->head, next, node) { unsigned int eflags_local = PKGCONF_PKG_ERRF_OK; pkgconf_dependency_t *depnode = node->data; @@ -1470,6 +1470,14 @@ pkgconf_pkg_walk_list(pkgconf_client_t *client, if (pkgdep->serial == client->serial) { pkgdep->hits++; + /* In this case we have a circular reference. + * We break that by deleteing the circular node from the + * the list, so that we dont create a situation where + * memory is leaked due to circular ownership. + * i.e: A owns B owns A + */ + pkgconf_node_delete(node, deplist); + pkgconf_dependency_unref(client, depnode); goto next; }