From 7476fff8f2183db824ea209f764a29c66e5e61ce Mon Sep 17 00:00:00 2001 From: Egor Ignatov Date: Thu, 8 Oct 2026 19:59:29 +0500 Subject: [PATCH] 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. (cherry picked from commit 04567a3b5e2e29a2252e89be8a3c625c692103d3) --- src/resolve/resolved-manager.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 8997ba0c35..9dcf9dcc6b 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -2173,12 +2173,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,