From 060b0d2f703b24086157697b075185d6176713ea Mon Sep 17 00:00:00 2001 From: dongshengyuan <545258830@qq.com> Date: Wed, 12 Aug 2026 13:36:36 +0800 Subject: [PATCH 1/3] resolvectl: reject tlsa without a domain The tlsa command accepts an optional service family before the domain list. When the only argument was "tcp", "udp", or "sctp", we consumed it as the family and returned success without issuing any query. Reproducer: build/resolvectl tlsa tcp Before: the command printed nothing and exited with status 0. Follow-up for: ebbc70e511c8b18f299f58dd641805eaab603865 --- src/resolve/resolvectl.c | 3 +++ test/units/TEST-75-RESOLVED.sh | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index 9af5626059..5e51664763 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -1161,6 +1161,9 @@ static int verb_tlsa(int argc, char *argv[], uintptr_t _data, void *userdata) { } else args = strv_skip(argv, 1); + if (strv_isempty(args)) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "The tlsa command requires at least one domain."); + STRV_FOREACH(p, args) RET_GATHER(ret, resolve_tlsa(family, *p)); diff --git a/test/units/TEST-75-RESOLVED.sh b/test/units/TEST-75-RESOLVED.sh index 85e9e4cc84..d3a7d38259 100755 --- a/test/units/TEST-75-RESOLVED.sh +++ b/test/units/TEST-75-RESOLVED.sh @@ -627,6 +627,8 @@ testcase_08_resolved() { grep -qF '"data":"' "$RUN_OUT" (! run resolvectl openpgp mr.smith@signed.test --json=short --type=A) grep -qF -- "The openpgp command may only be combined with --type=OPENPGPKEY." "$RUN_OUT" + (! run resolvectl tlsa tcp) + grep -qF -- "The tlsa command requires at least one domain." "$RUN_OUT" (! run resolvectl tlsa signed.test:invalid --json=short) grep -qF 'Invalid port "invalid".' "$RUN_OUT" (! run resolvectl tlsa signed.test --json=short --type=A) From 0cfa2d4f4c7c9d91d32294cba5bed8678ee06ea9 Mon Sep 17 00:00:00 2001 From: dongshengyuan <545258830@qq.com> Date: Wed, 12 Aug 2026 13:38:34 +0800 Subject: [PATCH 2/3] resolved: keep parsing DNS delegate servers after duplicates The DNS delegate parser tries to filter duplicate DNS= entries, but the duplicate branch returned from the whole parser. This made a duplicate server truncate the rest of the same DNS= line, silently dropping later valid servers. Reproducer: DNS=192.168.77.78 192.168.77.78 192.168.77.79 Before: only 192.168.77.78 appeared in the delegate server list. Follow-up for: 7928c0e0a13cdcc068e58c9ff9106cf40d17ab1b --- src/resolve/resolved-dns-delegate.c | 2 +- test/units/TEST-75-RESOLVED.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/resolve/resolved-dns-delegate.c b/src/resolve/resolved-dns-delegate.c index db34916a29..bfe2860366 100644 --- a/src/resolve/resolved-dns-delegate.c +++ b/src/resolve/resolved-dns-delegate.c @@ -281,7 +281,7 @@ int config_parse_delegate_dns_servers( /* Drop the marker. This is used to find the servers that ceased to exist, see * manager_mark_dns_servers() and manager_flush_marked_dns_servers(). */ dns_server_move_back_and_unmark(s); - return 0; + continue; } r = dns_server_new( diff --git a/test/units/TEST-75-RESOLVED.sh b/test/units/TEST-75-RESOLVED.sh index d3a7d38259..ad4e8f8a42 100755 --- a/test/units/TEST-75-RESOLVED.sh +++ b/test/units/TEST-75-RESOLVED.sh @@ -1493,7 +1493,7 @@ testcase_delegate() { mkdir -p /run/systemd/dns-delegate.d/ cat >/run/systemd/dns-delegate.d/testcase.dns-delegate < Date: Wed, 12 Aug 2026 13:42:40 +0800 Subject: [PATCH 3/3] resolved: allow full replacement of link domains SetLinkDomains() marks old link domains and then builds the replacement list in place. The marked old domains still counted against LINK_SEARCH_DOMAINS_MAX, so replacing a non-empty list with exactly the maximum number of new domains failed while adding the last entry. The error path then unlinked all domains, so a failed setter call also destroyed the previous configuration. Reproducer: resolvectl domain dnsbug1 old.example busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1 \ org.freedesktop.resolve1.Manager SetLinkDomains 'ia(sb)' "$ifindex" 1024 "${args[@]}" resolvectl domain dnsbug1 Before: the bus call failed with "Argument list too long" and the link's domain list became empty. Follow-up for: d2ec6608b93e3f74345c737637af24e9e75c209b --- src/resolve/resolved-link-bus.c | 4 ++++ test/units/TEST-75-RESOLVED.sh | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c index a269414ccf..0f341d740a 100644 --- a/src/resolve/resolved-link-bus.c +++ b/src/resolve/resolved-link-bus.c @@ -392,6 +392,10 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_ dns_search_domain_move_back_and_unmark(d); else { r = dns_search_domain_new(l->manager, &d, DNS_SEARCH_DOMAIN_LINK, l, /* delegate= */ NULL, name); + if (r == -E2BIG) { + changed = dns_search_domain_unlink_marked(l->search_domains) || changed; + r = dns_search_domain_new(l->manager, &d, DNS_SEARCH_DOMAIN_LINK, l, /* delegate= */ NULL, name); + } if (r < 0) goto clear; diff --git a/test/units/TEST-75-RESOLVED.sh b/test/units/TEST-75-RESOLVED.sh index ad4e8f8a42..44cc71ba9f 100755 --- a/test/units/TEST-75-RESOLVED.sh +++ b/test/units/TEST-75-RESOLVED.sh @@ -290,6 +290,21 @@ manual_testcase_01_resolvectl() { assert_in "DOMAINS=~route-only-change.example.com" "$(cat "$hoge_state")" assert_not_in "route-only-change.example.com" "$(cat /run/systemd/resolve/resolv.conf /run/systemd/resolve/stub-resolv.conf)" + resolvectl domain hoge "old.example.com" + local domains=() + for i in {1..1025}; do + domains+=("too-many-$i.example.com") + done + (! resolvectl domain hoge "${domains[@]}") + assert_in 'old.example.com' "$(resolvectl domain hoge)" + + domains=() + for i in {1..1024}; do + domains+=("replacement-$i.example.com") + done + resolvectl domain hoge "${domains[@]}" + assert_not_in 'old.example.com' "$(resolvectl domain hoge)" + assert_in 'replacement-1024.example.com' "$(resolvectl domain hoge)" echo -e "nameserver 10.0.2.1\ndomain test-domain.example.com" | SYSTEMD_INVOKED_AS=resolvconf resolvectl -x -a hoge assert_in 'test-domain.example.com' "$(resolvectl domain hoge)" assert_in '~.' "$(resolvectl domain hoge)"