From ced6b50d6bfb9f97b12cbbc1126cefe14bc21cd7 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 29 Sep 2026 09:19:03 +0200 Subject: [PATCH] BUG/MEDIUM: resolvers: skip the data of ignored additional records When parsing the additional records of an SRV response, records which are not A or AAAA, or whose family is not accepted by dns-accept-family, are ignored, but resolv_validate_dns_response() then moves on to the next record without skipping the ignored record's data. The next record's name is thus read from the middle of the ignored one's data, which usually fails and makes all remaining additional records be ignored as well (resolv_read_name() fails or returns an empty name, and the loop continues at the same place), or may even produce bogus records if the data happens to look like a valid record. The glue records carrying the SRV targets' addresses are then lost, and the servers' addresses have to be resolved with extra A/AAAA queries. Since commit c84c15d39 ("BUG/MINOR: resolvers: Apply dns-accept-family setting on additional records") this also concerns AAAA records when IPv6 is not accepted, which is the default on hosts without IPv6 connectivity (dns-accept-family defaults to "auto"), so any SRV response with AAAA glue records placed before the A ones is affected there. This can be reproduced with "dns-accept-family ipv4" and an SRV response whose additional section contains an AAAA record for the first target followed by A records for all targets: the A records are never used and A queries are sent for all targets. Let's skip the record's data when ignoring it. The problem has existed for unknown record types since the additional records parsing was introduced. This must be backported to all stable branches. --- src/resolvers.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/resolvers.c b/src/resolvers.c index 776b8a999..910267bbc 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -1573,6 +1573,8 @@ static int resolv_validate_dns_response(unsigned char *resp, unsigned char *bufe memcpy(&answer_record->data.in6.sin6_addr, reader, answer_record->data_len); } else { + /* ignored record, skip its data */ + reader += answer_record->data_len; pool_free(resolv_answer_item_pool, answer_record); answer_record = NULL; continue; -- 2.47.3