Compare commits

...

6 Commits

Author SHA1 Message Date
Evan Hunt
3878c145c9 experiment 2025-02-26 16:01:01 -08:00
Evan Hunt
4acbfbc2d1 retry fix 2025-02-26 16:01:01 -08:00
Evan Hunt
1ef9a32de7 slight refactoring in validated()
fix some minor code redundancies.
2025-02-26 15:28:57 -08:00
Evan Hunt
6c738fe323 simplify dns_ncache_add()
there's no longer any reason to have both dns_ncache_add() and
dns_ncache_addoptout().
2025-02-26 15:28:57 -08:00
Evan Hunt
49ccbe857a fix: dev: Validating ADB fetches could cause a crash in import_rdataset()
Previously, in some cases, the resolver could return rdatasets of type CNAME or DNAME without the result code being set to `DNS_R_CNAME` or `DNS_R_DNAME`. This could trigger an assertion failure in the ADB. The resolver error has been fixed.

Closes #5201

Merge branch '5201-adb-cname-error' into 'main'

See merge request isc-projects/bind9!10172
2025-02-26 20:34:27 +00:00
Evan Hunt
1edbbc32b4 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.
2025-02-25 21:29:19 -08:00
4 changed files with 67 additions and 69 deletions

View File

@@ -567,6 +567,14 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
rdataset->ttl = ttlclamp(rdataset->ttl);
}
if (rdtype != dns_rdatatype_a && rdtype != dns_rdatatype_aaaa) {
char rb[DNS_RDATATYPE_FORMATSIZE];
char nb[DNS_NAME_FORMATSIZE];
dns_rdatatype_format(rdtype, rb, sizeof(rb));
dns_name_format(adbname->name, nb, sizeof(nb));
isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
"%s has %s", nb, rb);
}
REQUIRE(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;

View File

@@ -54,21 +54,16 @@
isc_result_t
dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t minttl,
dns_ttl_t maxttl, dns_rdataset_t *addedrdataset);
isc_result_t
dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
dns_dbnode_t *node, dns_rdatatype_t covers,
isc_stdtime_t now, dns_ttl_t minttl, dns_ttl_t maxttl,
bool optout, dns_rdataset_t *addedrdataset);
dns_ttl_t maxttl, bool optout, bool secure,
dns_rdataset_t *addedrdataset);
/*%<
* Convert the authority data from 'message' into a negative cache
* rdataset, and store it in 'cache' at 'node' with a TTL limited to
* 'maxttl'.
*
* \li dns_ncache_add produces a negative cache entry with a trust of no
* more than answer
* \li dns_ncache_addoptout produces a negative cache entry which will have
* a trust of secure if all the records that make up the entry are secure.
* \li if 'secure' is true and all the records that make up the entry
* are secure, then dns_ncache_add produces a negative cache entry
* with trust level secure.
*
* The 'covers' argument is the RR type whose nonexistence we are caching,
* or dns_rdatatype_any when caching a NXDOMAIN response.

View File

@@ -50,12 +50,6 @@ atomic_getuint8(isc_buffer_t *b) {
return ret;
}
static isc_result_t
addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t minttl,
dns_ttl_t maxttl, bool optout, bool secure,
dns_rdataset_t *addedrdataset);
static isc_result_t
copy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
isc_result_t result;
@@ -107,25 +101,8 @@ copy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
isc_result_t
dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t minttl,
dns_ttl_t maxttl, dns_rdataset_t *addedrdataset) {
return addoptout(message, cache, node, covers, now, minttl, maxttl,
false, false, addedrdataset);
}
isc_result_t
dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
dns_dbnode_t *node, dns_rdatatype_t covers,
isc_stdtime_t now, dns_ttl_t minttl, dns_ttl_t maxttl,
bool optout, dns_rdataset_t *addedrdataset) {
return addoptout(message, cache, node, covers, now, minttl, maxttl,
optout, true, addedrdataset);
}
static isc_result_t
addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t minttl,
dns_ttl_t maxttl, bool optout, bool secure,
dns_rdataset_t *addedrdataset) {
dns_ttl_t maxttl, bool optout, bool secure,
dns_rdataset_t *addedrdataset) {
isc_result_t result;
isc_buffer_t buffer;
isc_region_t r;

View File

@@ -5263,7 +5263,7 @@ validated(void *arg) {
* is returned, and that the rdatasets are bound.
*/
if (val->result == ISC_R_SUCCESS && !negative &&
val->rdataset != NULL && CHAINING(val->rdataset))
CHAINING(val->rdataset))
{
if (val->rdataset->type == dns_rdatatype_cname) {
eresult = DNS_R_CNAME;
@@ -5357,18 +5357,14 @@ validated(void *arg) {
nextval = ISC_LIST_HEAD(fctx->validators);
if (nextval != NULL) {
dns_validator_send(nextval);
goto cleanup_fetchctx;
} else if (sentresponse) {
done = true;
goto cleanup_fetchctx;
} else if (result == DNS_R_BROKENCHAIN) {
done = true;
goto cleanup_fetchctx;
} else {
fctx_try(fctx, true);
goto cleanup_fetchctx;
}
UNREACHABLE();
goto cleanup_fetchctx;
}
if (negative) {
@@ -5659,11 +5655,22 @@ answer_response:
* Negative results must be indicated in val->result.
*/
INSIST(hresp->rdataset != NULL);
if (dns_rdataset_isassociated(hresp->rdataset) &&
NEGATIVE(hresp->rdataset))
{
INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
eresult == DNS_R_NCACHENXRRSET);
if (dns_rdataset_isassociated(hresp->rdataset)) {
if (NEGATIVE(hresp->rdataset)) {
INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
eresult == DNS_R_NCACHENXRRSET);
} else if (eresult == ISC_R_SUCCESS) {
switch (hresp->rdataset->type) {
case dns_rdatatype_cname:
eresult = DNS_R_CNAME;
break;
case dns_rdatatype_dname:
eresult = DNS_R_DNAME;
break;
default:
break;
}
}
}
hresp->result = eresult;
@@ -6313,11 +6320,22 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message,
* Negative results must be indicated in
* resp->result.
*/
if (dns_rdataset_isassociated(resp->rdataset) &&
NEGATIVE(resp->rdataset))
{
INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
eresult == DNS_R_NCACHENXRRSET);
if (dns_rdataset_isassociated(resp->rdataset)) {
if (NEGATIVE(resp->rdataset)) {
INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
eresult == DNS_R_NCACHENXRRSET);
} else if (eresult == ISC_R_SUCCESS) {
switch (resp->rdataset->type) {
case dns_rdatatype_cname:
eresult = DNS_R_CNAME;
break;
case dns_rdatatype_dname:
eresult = DNS_R_DNAME;
break;
default:
break;
}
}
}
resp->result = eresult;
if (adbp != NULL && *adbp != NULL) {
@@ -6382,8 +6400,7 @@ cache_message(fetchctx_t *fctx, dns_message_t *message,
}
/*
* Do what dns_ncache_addoptout() does, and then compute an appropriate
* eresult.
* Call dns_ncache_add() and then compute an appropriate eresult.
*/
static isc_result_t
ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
@@ -6397,14 +6414,9 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
dns_rdataset_init(&rdataset);
ardataset = &rdataset;
}
if (secure) {
result = dns_ncache_addoptout(message, cache, node, covers, now,
minttl, maxttl, optout,
ardataset);
} else {
result = dns_ncache_add(message, cache, node, covers, now,
minttl, maxttl, ardataset);
}
result = dns_ncache_add(message, cache, node, covers, now, optout,
secure, minttl, maxttl, ardataset);
if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) {
/*
* If the cache now contains a negative entry and we
@@ -6422,15 +6434,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;
}