dnsmasq/dnsmasq-2.85-serv_domain-rh2186481.patch
Petr Menšík 0b70f00773 Correct releasing of serv_domain
In case the server->serv_domain points to domain also when it is not the
last server used, ensure the reference to last_server is always reset.
Some records might reference the server_domain, but cannot ever become
last_server. Such as server=/example.com/#

Do proper check also for above case and do not delete used serv_domain
structure. Also do optimization to reuse common server domains and do
not create new entry to already existing one.

Do two step cleaning during nameservers cleanup stage. Should avoid any
invalid pointer present.

Resolves: rhbz#2188712
2023-05-04 16:17:10 +02:00

109 lines
3.0 KiB
Diff

From c0e0202736f55195104dad9fec98c20d0d15df21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Fri, 21 Apr 2023 17:04:53 +0200
Subject: [PATCH] Correct releasing of serv_domain
In case the server->serv_domain points to domain also when it is not the
last server used, ensure the reference to last_server is always reset.
Some records might reference the server_domain, but cannot ever become
last_server. Such as server=/example.com/#
Correct detection of used server_domains for standard resolvers case.
Mark domain used even in that case, so it is not freed during
resolv.conf reading or other nameservers change.
---
src/network.c | 40 +++++++++++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 9 deletions(-)
diff --git a/src/network.c b/src/network.c
index cf2f2e2..8152cac 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1511,7 +1511,18 @@ void mark_servers(int flag)
}
}
-static void server_domains_cleanup(void)
+static void server_domains_pre_cleanup(void)
+{
+ struct server_domain *sd;
+
+ /* reset removed last_server. */
+ for (sd = daemon->server_domains; sd; sd = sd->next)
+ if ((sd->flags & SERV_MARK) == 0 && sd->last_server &&
+ (sd->last_server->flags & SERV_MARK) != 0)
+ sd->last_server = NULL;
+}
+
+static void server_domains_post_cleanup(void)
{
struct server_domain *sd, *tmp, **up;
@@ -1528,8 +1539,6 @@ static void server_domains_cleanup(void)
}
else {
up = &sd->next;
- if (sd->last_server && (sd->last_server->flags & SERV_MARK))
- sd->last_server = NULL;
}
}
}
@@ -1538,7 +1547,7 @@ void cleanup_servers(void)
{
struct server *serv, *tmp, **up;
- server_domains_cleanup();
+ server_domains_pre_cleanup();
/* unlink and free anything still marked. */
for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
@@ -1552,10 +1561,16 @@ void cleanup_servers(void)
free(serv->domain);
free(serv);
}
- else
- up = &serv->next;
+ else
+ {
+ up = &serv->next;
+ if (serv->serv_domain && (serv->serv_domain->flags & SERV_MARK) != 0)
+ serv->serv_domain = NULL;
+ }
}
+ server_domains_post_cleanup();
+
#ifdef HAVE_LOOP
/* Now we have a new set of servers, test for loops. */
loop_send_probes();
@@ -1699,7 +1714,11 @@ static void server_domain_check(struct server *serv)
if (sd)
sd->flags &= (~SERV_MARK); /* found domain, mark active */
else
- server_domain_new(serv);
+ {
+ sd = server_domain_find_domain(serv->domain);
+ if (!sd)
+ server_domain_new(serv);
+ }
}
void check_servers(void)
@@ -1808,8 +1827,11 @@ void check_servers(void)
else if (strlen(serv->domain) == 0)
s1 = _("default"), s2 = "";
else
- s1 = _("domain"), s2 = serv->domain;
-
+ {
+ s1 = _("domain"), s2 = serv->domain;
+ server_domain_check(serv);
+ }
+
if (serv->flags & SERV_NO_ADDR)
{
count--;
--
2.39.2