resolve: get the current DNS server before passing the server lists

manager_get_dns_server() may re-read /etc/resolv.conf and replace
m->dns_servers and m->search_domains, but it was passed as an argument
to dns_configuration_json_append() together with those lists, and the
order of evaluation of the arguments is unspecified. gcc with LTO reads
the list heads first, so after a foreign /etc/resolv.conf has changed
the freed lists are walked. Typically the serialization then fails with
EUCLEAN, which makes the SubscribeDNSConfiguration method of
io.systemd.Resolve.Monitor and in turn systemd-networkd-wait-online
--dns fail.

Call manager_get_dns_server() first and store the result in a local
variable.
This commit is contained in:
Egor Ignatov authored and Nick Rosbrook committed 2026-10-09 15:10:25 -04:00
1 parent 13bf80491b
commit 04567a3b5e
1 file changed
+5 -1
+5 -1
View File
@@ -2165,12 +2165,16 @@ static int global_dns_configuration_json_append(Manager *m, sd_json_variant **co
if (r < 0)
return r;
/* This may re-read /etc/resolv.conf and replace m->dns_servers and m->search_domains, hence call it
* before they are passed below, as the order of evaluation of the arguments is unspecified. */
DnsServer *current_dns_server = manager_get_dns_server(m);
return dns_configuration_json_append(
/* ifname= */ NULL,
/* ifindex= */ 0,
/* delegate= */ NULL,
/* default_route= */ -1,
manager_get_dns_server(m),
current_dns_server,
m->dns_servers,
m->fallback_dns_servers,
m->search_domains,