From: W.C.A. Wijngaards Date: Mon, 18 May 2026 14:42:39 +0000 (+0200) Subject: - Fix for mixed class referrals, the resolver uses the query X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=a58bd6cb1e75a013de2344cefab0e3763764d8cb;p=thirdparty%2Funbound.git - Fix for mixed class referrals, the resolver uses the query class. Thanks to Xin Wang and Jiajia Liu, Northwestern Polytechnical University, for the report. --- diff --git a/doc/Changelog b/doc/Changelog index 42a2192ac..a51918e28 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,8 @@ +18 May 2026: Wouter + - Fix for mixed class referrals, the resolver uses the query + class. Thanks to Xin Wang and Jiajia Liu, Northwestern + Polytechnical University, for the report. + 15 May 2026: Wouter - Fix man page entry for so-sndbuf, it is for responses sent out. - Fix val_find_DS for robustness, to check the result of diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c index be5bf482d..5b609c960 100644 --- a/iterator/iter_delegpt.c +++ b/iterator/iter_delegpt.c @@ -398,11 +398,12 @@ delegpt_count_missing_targets(struct delegpt* dp, int* alllame) /** find NS rrset in given list */ static struct ub_packed_rrset_key* -find_NS(struct reply_info* rep, size_t from, size_t to) +find_NS(struct reply_info* rep, size_t from, size_t to, uint16_t qclass) { size_t i; for(i=from; irrsets[i]->rk.type) == LDNS_RR_TYPE_NS) + if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS && + ntohs(rep->rrsets[i]->rk.rrset_class) == qclass) return rep->rrsets[i]; } return NULL; @@ -416,12 +417,14 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region) size_t i; /* look for NS records in the authority section... */ ns_rrset = find_NS(msg->rep, msg->rep->an_numrrsets, - msg->rep->an_numrrsets+msg->rep->ns_numrrsets); + msg->rep->an_numrrsets+msg->rep->ns_numrrsets, + msg->qinfo.qclass); /* In some cases (even legitimate, perfectly legal cases), the * NS set for the "referral" might be in the answer section. */ if(!ns_rrset) - ns_rrset = find_NS(msg->rep, 0, msg->rep->an_numrrsets); + ns_rrset = find_NS(msg->rep, 0, msg->rep->an_numrrsets, + msg->qinfo.qclass); /* If there was no NS rrset in the authority section, then this * wasn't a referral message. (It might not actually be a @@ -447,10 +450,12 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region) i < (msg->rep->an_numrrsets+msg->rep->ns_numrrsets)) continue; - if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) { + if(ntohs(s->rk.type) == LDNS_RR_TYPE_A && + ntohs(s->rk.rrset_class) == msg->qinfo.qclass) { if(!delegpt_add_rrset_A(dp, region, s, 0, NULL)) return NULL; - } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) { + } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA && + ntohs(s->rk.rrset_class) == msg->qinfo.qclass) { if(!delegpt_add_rrset_AAAA(dp, region, s, 0, NULL)) return NULL; } diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c index 37c4150cd..8870fb1dd 100644 --- a/iterator/iter_scrub.c +++ b/iterator/iter_scrub.c @@ -732,6 +732,11 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg, "RRset:", pkt, msg, prev, &rrset); continue; } + if(ntohs(rrset->rrset_class) != qinfo->qclass) { + remove_rrset("normalize: removing other class " + "RRset:", pkt, msg, prev, &rrset); + continue; + } if(nsset == NULL) { nsset = rrset; } else { diff --git a/testdata/iter_class_mixreferral.rpl b/testdata/iter_class_mixreferral.rpl new file mode 100644 index 000000000..2438825b4 --- /dev/null +++ b/testdata/iter_class_mixreferral.rpl @@ -0,0 +1,144 @@ +; config options +server: + target-fetch-policy: "0 0 0 0 0" + qname-minimisation: "no" + minimal-responses: no + iter-scrub-promiscuous: no + +stub-zone: + name: "." + stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. +CONFIG_END + +SCENARIO_BEGIN Test referral with mixed class items + +; K.ROOT-SERVERS.NET. +RANGE_BEGIN 0 100 + ADDRESS 193.0.14.129 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +. IN NS +SECTION ANSWER +. IN NS K.ROOT-SERVERS.NET. +SECTION ADDITIONAL +K.ROOT-SERVERS.NET. IN A 193.0.14.129 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION AUTHORITY +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END +RANGE_END + +; a.gtld-servers.net. +RANGE_BEGIN 0 100 + ADDRESS 192.5.6.30 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +com. IN NS +SECTION ANSWER +com. IN NS a.gtld-servers.net. +SECTION ADDITIONAL +a.gtld-servers.net. IN A 192.5.6.30 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +example.com. IN NS +SECTION AUTHORITY +; mixed class contents +example.com. CH NS ch.example.com. +example.com. IN NS ns.example.com. +SECTION ADDITIONAL +ch.example.com. CH A 1.2.3.5 +ns.example.com. IN A 1.2.3.4 +ENTRY_END +RANGE_END + +; ns.example.com. +RANGE_BEGIN 0 100 + ADDRESS 1.2.3.4 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +example.com. IN NS +SECTION ANSWER +example.com. IN NS ns.example.com. +SECTION ADDITIONAL +ns.example.com. IN A 1.2.3.4 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +ENTRY_END +RANGE_END + +; ch.example.com. +RANGE_BEGIN 0 100 + ADDRESS 1.2.3.5 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +example.com. IN NS +SECTION ANSWER +example.com. IN NS ch.example.com. +SECTION ADDITIONAL +ch.example.com. IN A 1.2.3.5 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.42 +ENTRY_END +RANGE_END + +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.example.com. IN A +ENTRY_END + +; recursion happens here. +STEP 10 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +ENTRY_END + +SCENARIO_END