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
This commit is contained in:
Petr Menšík 2023-04-21 17:18:22 +02:00
parent a84d6321e9
commit 0b70f00773
2 changed files with 115 additions and 1 deletions

View File

@ -0,0 +1,108 @@
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

View File

@ -20,7 +20,7 @@
Name: dnsmasq
Version: 2.85
Release: 7%{?extraversion:.%{extraversion}}%{?dist}
Release: 8%{?extraversion:.%{extraversion}}%{?dist}
Summary: A lightweight DHCP/caching DNS server
License: GPLv2 or GPLv3
@ -53,6 +53,9 @@ Patch7: dnsmasq-2.87-CVE-2022-0934.patch
Patch8: dnsmasq-2.79-server-domain-fixup.patch
# https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;h=eb92fb32b746f2104b0f370b5b295bb8dd4bd5e5
Patch9: dnsmasq-2.89-edns0-size.patch
# Downstream only patch; https://bugzilla.redhat.com/show_bug.cgi?id=2186481
# Fixes issue in Patch4
Patch10: dnsmasq-2.85-serv_domain-rh2186481.patch
# This is workaround to nettle bug #1549190
# https://bugzilla.redhat.com/show_bug.cgi?id=1549190
@ -196,6 +199,9 @@ install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/%{name}.conf
%{_mandir}/man1/dhcp_*
%changelog
* Fri Apr 21 2023 Petr Menšík <pemensik@redhat.com> - 2.85-8
- Correct possible crashes when server=/example.net/# is used (#2188712)
* Mon Apr 03 2023 Petr Menšík <pemensik@redhat.com> - 2.85-7
- Limit offered EDNS0 size 1232 (CVE-2023-28450)