From: Christopher Faulet Date: Tue, 29 Sep 2026 07:19:03 +0000 (+0200) Subject: BUG/MEDIUM: resolvers: skip the data of ignored additional records X-Git-Url: https://git.kaiwu.me/$%7BGITURL%7D$%7Bcid%7D?a=commitdiff_plain;h=ced6b50d6bfb9f97b12cbbc1126cefe14bc21cd7;p=haproxy.git 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. --- 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;