From c724e008771aaaed70f909cb28fdcab1c9244d22 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 18 May 2015 23:23:17 +0200 Subject: [PATCH] resolved: fix crash when shutting down MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported by Cristian Rodríguez http://lists.freedesktop.org/archives/systemd-devel/2015-May/031626.html (cherry picked from commit cab5b05903096e1c9cf5575ccc73f89d15c8db69) Cherry-picked from: cab5b05 Resolves: #1222517 --- src/resolve/resolved-dns-cache.c | 4 +--- src/resolve/resolved-dns-server.c | 15 ++++++++------- src/resolve/resolved-link.c | 6 +++--- src/resolve/resolved-manager.c | 4 ++-- src/shared/prioq.c | 6 ++++-- src/shared/prioq.h | 2 +- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index 33ca4d1a4..874207cfb 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -93,9 +93,7 @@ void dns_cache_flush(DnsCache *c) { hashmap_free(c->by_key); c->by_key = NULL; - - prioq_free(c->by_expiry); - c->by_expiry = NULL; + c->by_expiry = prioq_free(c->by_expiry); } static void dns_cache_remove(DnsCache *c, DnsResourceKey *key) { diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c index caf06fe45..9a62a6325 100644 --- a/src/resolve/resolved-dns-server.c +++ b/src/resolve/resolved-dns-server.c @@ -78,23 +78,24 @@ DnsServer* dns_server_free(DnsServer *s) { if (!s) return NULL; - if (s->manager) { + if (s->link) { if (s->type == DNS_SERVER_LINK) LIST_REMOVE(servers, s->link->dns_servers, s); - else if (s->type == DNS_SERVER_SYSTEM) + + if (s->link->current_dns_server == s) + link_set_dns_server(s->link, NULL); + } + + if (s->manager) { + if (s->type == DNS_SERVER_SYSTEM) LIST_REMOVE(servers, s->manager->dns_servers, s); else if (s->type == DNS_SERVER_FALLBACK) LIST_REMOVE(servers, s->manager->fallback_dns_servers, s); - else - assert_not_reached("Unknown server type"); if (s->manager->current_dns_server == s) manager_set_dns_server(s->manager, NULL); } - if (s->link && s->link->current_dns_server == s) - link_set_dns_server(s->link, NULL); - free(s); return NULL; diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index f94e4bb6f..27d9129e0 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -68,13 +68,13 @@ Link *link_free(Link *l) { if (l->manager) hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex)); + while (l->dns_servers) + dns_server_free(l->dns_servers); + dns_scope_free(l->unicast_scope); dns_scope_free(l->llmnr_ipv4_scope); dns_scope_free(l->llmnr_ipv6_scope); - while (l->dns_servers) - dns_server_free(l->dns_servers); - free(l); return NULL; } diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index b5ad70161..7c253aa13 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -536,11 +536,11 @@ Manager *manager_free(Manager *m) { while (m->dns_queries) dns_query_free(m->dns_queries); - dns_scope_free(m->unicast_scope); - manager_flush_dns_servers(m, DNS_SERVER_SYSTEM); manager_flush_dns_servers(m, DNS_SERVER_FALLBACK); + dns_scope_free(m->unicast_scope); + hashmap_free(m->links); hashmap_free(m->dns_transactions); diff --git a/src/shared/prioq.c b/src/shared/prioq.c index 8af4c51c2..b89888be0 100644 --- a/src/shared/prioq.c +++ b/src/shared/prioq.c @@ -45,12 +45,14 @@ Prioq *prioq_new(compare_func_t compare_func) { return q; } -void prioq_free(Prioq *q) { +Prioq* prioq_free(Prioq *q) { if (!q) - return; + return NULL; free(q->items); free(q); + + return NULL; } int prioq_ensure_allocated(Prioq **q, compare_func_t compare_func) { diff --git a/src/shared/prioq.h b/src/shared/prioq.h index d836b36cd..1c044b135 100644 --- a/src/shared/prioq.h +++ b/src/shared/prioq.h @@ -28,7 +28,7 @@ typedef struct Prioq Prioq; #define PRIOQ_IDX_NULL ((unsigned) -1) Prioq *prioq_new(compare_func_t compare); -void prioq_free(Prioq *q); +Prioq *prioq_free(Prioq *q); int prioq_ensure_allocated(Prioq **q, compare_func_t compare_func); int prioq_put(Prioq *q, void *data, unsigned *idx);