From 46e793a3b4e63ff7d4cf941b8a5abc493fd8794d Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Tue, 25 Feb 2025 14:41:41 -0800 Subject: [PATCH 1/2] set eresult based on the type in ncache_adderesult() when the caching of a negative record failed because of the presence of a positive one, ncache_adderesult() could override this to ISC_R_SUCCESS. this could cause CNAME and DNAME responses to be handled incorrectly. ncache_adderesult() now sets the result code correctly in such cases. (cherry picked from commit 1edbbc32b4cca228e05cb9646ad623cf31027a95) --- lib/dns/resolver.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 3663b5a846..d67945e906 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -6908,15 +6908,21 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, } } else { /* - * Either we don't care about the nature of the - * cache rdataset (because no fetch is - * interested in the outcome), or the cache - * rdataset is not a negative cache entry. - * Whichever case it is, we can return success. - * - * XXXRTH There's a CNAME/DNAME problem here. + * The attempt to add a negative cache entry + * was rejected. Set *eresultp to reflect + * the type of the dataset being returned. */ - *eresultp = ISC_R_SUCCESS; + switch (ardataset->type) { + case dns_rdatatype_cname: + *eresultp = DNS_R_CNAME; + break; + case dns_rdatatype_dname: + *eresultp = DNS_R_DNAME; + break; + default: + *eresultp = ISC_R_SUCCESS; + break; + } } result = ISC_R_SUCCESS; } From 04d18f31cec5758ce237e5c6d7897f92279ace1b Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Wed, 26 Feb 2025 14:56:46 -0800 Subject: [PATCH 2/2] fix the fetchresponse result for CNAME/DNAME the fix in commit 1edbbc32b4 was incomplete; the wrong event result could also be set in cache_name() and validated(). (cherry picked from commit 9ebeb60174f3074f96b7c00dcda852a5bd61bad6) --- lib/dns/resolver.c | 47 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index d67945e906..4d3491c4a9 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -6146,11 +6146,24 @@ answer_response: * Negative results must be indicated in event->result. */ INSIST(hevent->rdataset != NULL); - if (dns_rdataset_isassociated(hevent->rdataset) && - NEGATIVE(hevent->rdataset)) - { - INSIST(eresult == DNS_R_NCACHENXDOMAIN || - eresult == DNS_R_NCACHENXRRSET); + if (dns_rdataset_isassociated(hevent->rdataset)) { + if (NEGATIVE(hevent->rdataset)) { + INSIST(eresult == DNS_R_NCACHENXDOMAIN || + eresult == DNS_R_NCACHENXRRSET); + } else if (eresult == ISC_R_SUCCESS && + hevent->rdataset->type != fctx->type) + { + switch (hevent->rdataset->type) { + case dns_rdatatype_cname: + eresult = DNS_R_CNAME; + break; + case dns_rdatatype_dname: + eresult = DNS_R_DNAME; + break; + default: + break; + } + } } hevent->result = eresult; @@ -6799,11 +6812,25 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message, * Negative results must be indicated in * event->result. */ - if (dns_rdataset_isassociated(event->rdataset) && - NEGATIVE(event->rdataset)) - { - INSIST(eresult == DNS_R_NCACHENXDOMAIN || - eresult == DNS_R_NCACHENXRRSET); + if (dns_rdataset_isassociated(event->rdataset)) { + if (NEGATIVE(event->rdataset)) { + INSIST(eresult == + DNS_R_NCACHENXDOMAIN || + eresult == DNS_R_NCACHENXRRSET); + } else if (eresult == ISC_R_SUCCESS && + event->rdataset->type != fctx->type) + { + switch (event->rdataset->type) { + case dns_rdatatype_cname: + eresult = DNS_R_CNAME; + break; + case dns_rdatatype_dname: + eresult = DNS_R_DNAME; + break; + default: + break; + } + } } event->result = eresult; if (adbp != NULL && *adbp != NULL) {