--- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -6984,15 +6984,19 @@ answer_response(fetchctx_t *fctx) { * a CNAME or DNAME). */ INSIST(!external); - if ((rdataset->type != - dns_rdatatype_cname) || - !found_dname || - (aflag == - DNS_RDATASETATTR_ANSWER)) + /* + * Don't use found_cname here + * as we have just set it + * above. + */ + if (cname == NULL && + !found_dname && + aflag == + DNS_RDATASETATTR_ANSWER) { have_answer = ISC_TRUE; - if (rdataset->type == - dns_rdatatype_cname) + if (found_cname && + cname == NULL) cname = name; name->attributes |= DNS_NAMEATTR_ANSWER;
if ((rdataset->type != dns_rdatatype_cname) || !found_dname || (aflag == DNS_RDATASETATTR_ANSWER)) if (cname == NULL && !found_dname && aflag == DNS_RDATASETATTR_ANSWER)
have_answer
variable to true. This is necessary to determine if the packet contained the answer to our query: 6968 if (found) {
found
variable is set in five code blocks from the same function, which handle different variations of the answers, such as name redirection by CNAME
or DNAME
records, response to a request with the ANY
type, etc.: 6891 if (rdataset->type == type && !found_cname) { 6892 /* 6893 * We've found an ordinary answer. 6894 */
6899 } else if (type == dns_rdatatype_any) { 6900 /* 6901 * We've found an answer matching 6902 * an ANY query. There may be 6903 * more. 6904 */
6907 } else if (rdataset->type == dns_rdatatype_rrsig 6908 && rdataset->covers == type 6909 && !found_cname) { 6910 /* 6911 * We've found a signature that 6912 * covers the type we're looking for. 6913 */
6917 } else if (rdataset->type == 6918 dns_rdatatype_cname 6919 && !found_type) { 6920 /* 6921 * We're looking for something else, 6922 * but we found a CNAME. 6923 *
6955 } else if (rdataset->type == dns_rdatatype_rrsig 6956 && rdataset->covers == 6957 dns_rdatatype_cname 6958 && !found_type) { 6959 /* 6960 * We're looking for something else, 6961 * but we found a SIG CNAME. 6962 */
“Named mishandled some responses where there was a result of failure. (CVE-2016-9147) ”
RRSIG
. RRSIG
is one of the DNSSEC
mechanisms that ensures the integrity of the DNS data in the response. For records of any type (A, AAAA, NS, DNAME, CNAME, etc.), the corresponding RRSIG
record is transmitted in the response, which contains a digital signature. In order to understand for which type of RRSIG
signature contains, there is a Type Covered
field in RRSIG
. 6907 } else if (rdataset->type == dns_rdatatype_rrsig 6908 && rdataset->covers == type 6909 && !found_cname) { 6910 /* 6911 * We've found a signature that 6912 * covers the type we're looking for. 6913 */ 6914 found = ISC_TRUE; 6915 found_type = ISC_TRUE; 6916 aflag = DNS_RDATASETATTR_ANSWERSIG;
6955 } else if (rdataset->type == dns_rdatatype_rrsig 6956 && rdataset->covers == 6957 dns_rdatatype_cname 6958 && !found_type) { 6959 /* 6960 * We're looking for something else, 6961 * but we found a SIG CNAME. 6962 */ 6963 found = ISC_TRUE; 6964 found_cname = ISC_TRUE; 6965 aflag = DNS_RDATASETATTR_ANSWERSIG; 6966 }
ANSWER_SECTION
. Indeed, this situation should not occur in normal DNS traffic, since RRSIG can not be tied to another record.Source: https://habr.com/ru/post/321428/
All Articles