mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-21 17:41:35 -04:00
Disable UPDATE and NOTIFY for non-IN classes
Return NOTIMP for UPDATE and NOTIFY requests received for views with a class other than IN. Only QUERY is now supported for non-IN views such as CHAOS. When running dns dns_rdata_tostruct() with types that are only defined for class IN, ensure that the class is correct before proceeding. Add an assertion that any zone being updated is of class IN. (Note that previously, a DLZ zone could have its class value set incorrectly to NONE; this has been fixed.) This addresses YWH-PGM40640-70 and YWH-PGM40640-73 (as well as any similar problems that might have occurred in the future) by minimizing the code paths that can be reached by rdata classes other than IN, so it is safe for the implementation to assume that rdatatypes that are only defined for class IN, such as SVCB or WKS, have been parsed and validated, and not accepted as unknown/opaque data. Fixes: isc-projects/bind9#5777 Fixes: isc-projects/bind9#5779
This commit is contained in:
parent
bfb027fecd
commit
6ba5e87a08
4 changed files with 34 additions and 22 deletions
|
|
@ -1715,6 +1715,7 @@ dlzconfigure_callback(dns_view_t *view, dns_dlzdb_t *dlzdb, dns_zone_t *zone) {
|
|||
dns_name_t *origin = dns_zone_getorigin(zone);
|
||||
dns_rdataclass_t zclass = view->rdclass;
|
||||
|
||||
dns_zone_setclass(zone, zclass);
|
||||
RETERR(dns_zonemgr_managezone(named_g_server->zonemgr, zone));
|
||||
|
||||
dns_zone_setstats(zone, named_g_server->zonestats);
|
||||
|
|
|
|||
|
|
@ -566,6 +566,9 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
|
|||
|
||||
rdtype = rdataset->type;
|
||||
|
||||
REQUIRE(rdataset->rdclass == dns_rdataclass_in);
|
||||
REQUIRE(dns_rdatatype_isaddr(rdtype));
|
||||
|
||||
switch (rdataset->trust) {
|
||||
case dns_trust_glue:
|
||||
case dns_trust_additional:
|
||||
|
|
@ -584,8 +587,6 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
|
|||
rdataset->ttl = ttlclamp(rdataset->ttl);
|
||||
}
|
||||
|
||||
REQUIRE(dns_rdatatype_isaddr(rdtype));
|
||||
|
||||
DNS_RDATASET_FOREACH(rdataset) {
|
||||
/* FIXME: Move to a separate function */
|
||||
dns_adbnamehooklist_t *hookhead = NULL;
|
||||
|
|
|
|||
|
|
@ -2459,6 +2459,10 @@ ns_client_request_continue(void *arg) {
|
|||
break;
|
||||
case dns_opcode_update:
|
||||
CTRACE("update");
|
||||
if (client->inner.view->rdclass != dns_rdataclass_in) {
|
||||
ns_client_error(client, DNS_R_NOTIMP);
|
||||
break;
|
||||
}
|
||||
#ifdef HAVE_DNSTAP
|
||||
dns_dt_send(client->inner.view, DNS_DTTYPE_UQ,
|
||||
&client->inner.peeraddr,
|
||||
|
|
@ -2472,6 +2476,10 @@ ns_client_request_continue(void *arg) {
|
|||
break;
|
||||
case dns_opcode_notify:
|
||||
CTRACE("notify");
|
||||
if (client->inner.view->rdclass != dns_rdataclass_in) {
|
||||
ns_client_error(client, DNS_R_NOTIMP);
|
||||
break;
|
||||
}
|
||||
ns_client_settimeout(client, 60);
|
||||
ns_notify_start(client, client->inner.handle);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -966,7 +966,9 @@ ssu_checkrr(void *data, rr_t *rr) {
|
|||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
target = &ptr.ptr;
|
||||
}
|
||||
if (rr->rdata.type == dns_rdatatype_srv) {
|
||||
if (rr->rdata.rdclass == dns_rdataclass_in &&
|
||||
rr->rdata.type == dns_rdatatype_srv)
|
||||
{
|
||||
result = dns_rdata_tostruct(&rr->rdata, &srv, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
target = &srv.target;
|
||||
|
|
@ -1311,7 +1313,10 @@ replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
if (db_rr->type == dns_rdatatype_wks) {
|
||||
|
||||
if (db_rr->rdclass == dns_rdataclass_in &&
|
||||
db_rr->type == dns_rdatatype_wks)
|
||||
{
|
||||
/*
|
||||
* Compare the address and protocol fields only. These
|
||||
* form the first five bytes of the RR data. Do a
|
||||
|
|
@ -1451,9 +1456,8 @@ add_rr_prepare_action(void *data, rr_t *rr) {
|
|||
* 'rdata', and 'ttl', respectively.
|
||||
*/
|
||||
static void
|
||||
get_current_rr(dns_rdataclass_t zoneclass, dns_name_t *name, dns_rdata_t *rdata,
|
||||
dns_rdatatype_t *covers, dns_ttl_t *ttl,
|
||||
dns_rdataclass_t *update_class) {
|
||||
get_current_rr(dns_name_t *name, dns_rdata_t *rdata, dns_rdatatype_t *covers,
|
||||
dns_ttl_t *ttl, dns_rdataclass_t *update_class) {
|
||||
dns_rdataset_t *rdataset;
|
||||
isc_result_t result;
|
||||
rdataset = ISC_LIST_HEAD(name->list);
|
||||
|
|
@ -1466,7 +1470,7 @@ get_current_rr(dns_rdataclass_t zoneclass, dns_name_t *name, dns_rdata_t *rdata,
|
|||
dns_rdataset_current(rdataset, rdata);
|
||||
INSIST(dns_rdataset_next(rdataset) == ISC_R_NOMORE);
|
||||
*update_class = rdata->rdclass;
|
||||
rdata->rdclass = zoneclass;
|
||||
rdata->rdclass = dns_rdataclass_in;
|
||||
}
|
||||
|
||||
/*%
|
||||
|
|
@ -1562,7 +1566,6 @@ send_update(ns_client_t *client, dns_zone_t *zone) {
|
|||
dns_message_t *request = client->message;
|
||||
isc_mem_t *mctx = client->manager->mctx;
|
||||
dns_aclenv_t *env = client->manager->aclenv;
|
||||
dns_rdataclass_t zoneclass;
|
||||
dns_rdatatype_t covers;
|
||||
dns_name_t *zonename = NULL;
|
||||
unsigned int *maxbytype = NULL;
|
||||
|
|
@ -1574,11 +1577,13 @@ send_update(ns_client_t *client, dns_zone_t *zone) {
|
|||
|
||||
CHECK(dns_zone_getdb(zone, &db));
|
||||
zonename = dns_db_origin(db);
|
||||
zoneclass = dns_db_class(db);
|
||||
dns_zone_getssutable(zone, &ssutable);
|
||||
options = dns_zone_getoptions(zone);
|
||||
dns_db_currentversion(db, &ver);
|
||||
|
||||
/* Updates are only supported for class IN. */
|
||||
INSIST(dns_zone_getclass(zone) == dns_rdataclass_in);
|
||||
|
||||
/*
|
||||
* Update message processing can leak record existence information
|
||||
* so check that we are allowed to query this zone. Additionally,
|
||||
|
|
@ -1623,13 +1628,12 @@ send_update(ns_client_t *client, dns_zone_t *zone) {
|
|||
dns_rdataclass_t update_class;
|
||||
|
||||
INSIST(ssutable == NULL || update < maxbytypelen);
|
||||
get_current_rr(zoneclass, name, &rdata, &covers, &ttl,
|
||||
&update_class);
|
||||
get_current_rr(name, &rdata, &covers, &ttl, &update_class);
|
||||
|
||||
if (!dns_name_issubdomain(name, zonename)) {
|
||||
FAILC(DNS_R_NOTZONE, "update RR is outside zone");
|
||||
}
|
||||
if (update_class == zoneclass) {
|
||||
if (update_class == dns_rdataclass_in) {
|
||||
/*
|
||||
* Check for meta-RRs. The RFC2136 pseudocode says
|
||||
* check for ANY|AXFR|MAILA|MAILB, but the text adds
|
||||
|
|
@ -1643,6 +1647,7 @@ send_update(ns_client_t *client, dns_zone_t *zone) {
|
|||
CLEANUP(DNS_R_REFUSED);
|
||||
}
|
||||
if ((options & DNS_ZONEOPT_CHECKSVCB) != 0 &&
|
||||
rdata.rdclass == dns_rdataclass_in &&
|
||||
rdata.type == dns_rdatatype_svcb)
|
||||
{
|
||||
result = dns_rdata_checksvcb(name, &rdata);
|
||||
|
|
@ -1731,7 +1736,6 @@ send_update(ns_client_t *client, dns_zone_t *zone) {
|
|||
}
|
||||
|
||||
if (update_class == dns_rdataclass_any &&
|
||||
zoneclass == dns_rdataclass_in &&
|
||||
(rdata.type == dns_rdatatype_ptr ||
|
||||
rdata.type == dns_rdatatype_srv))
|
||||
{
|
||||
|
|
@ -2629,7 +2633,6 @@ update_action(void *arg) {
|
|||
isc_mem_t *mctx = client->manager->mctx;
|
||||
dns_rdatatype_t covers;
|
||||
dns_message_t *request = client->message;
|
||||
dns_rdataclass_t zoneclass;
|
||||
dns_name_t *zonename = NULL;
|
||||
dns_fixedname_t tmpnamefixed;
|
||||
dns_name_t *tmpname = NULL;
|
||||
|
|
@ -2646,9 +2649,10 @@ update_action(void *arg) {
|
|||
|
||||
CHECK(dns_zone_getdb(zone, &db));
|
||||
zonename = dns_db_origin(db);
|
||||
zoneclass = dns_db_class(db);
|
||||
options = dns_zone_getoptions(zone);
|
||||
|
||||
INSIST(dns_zone_getclass(zone) == dns_rdataclass_in);
|
||||
|
||||
is_inline = (!dns_zone_israw(zone) && dns_zone_issecure(zone));
|
||||
is_maintain = (dns_zone_getkasp(zone) != NULL) && !dns_zone_israw(zone);
|
||||
is_signing = is_inline || is_maintain;
|
||||
|
|
@ -2669,8 +2673,7 @@ update_action(void *arg) {
|
|||
dns_rdataclass_t update_class;
|
||||
bool flag;
|
||||
|
||||
get_current_rr(zoneclass, name, &rdata, &covers, &ttl,
|
||||
&update_class);
|
||||
get_current_rr(name, &rdata, &covers, &ttl, &update_class);
|
||||
|
||||
if (ttl != 0) {
|
||||
PREREQFAILC(DNS_R_FORMERR,
|
||||
|
|
@ -2733,7 +2736,7 @@ update_action(void *arg) {
|
|||
"prerequisite not satisfied");
|
||||
}
|
||||
}
|
||||
} else if (update_class == zoneclass) {
|
||||
} else if (update_class == dns_rdataclass_in) {
|
||||
/* "temp<rr.name, rr.type> += rr;" */
|
||||
temp_append(&temp, name, &rdata);
|
||||
} else {
|
||||
|
|
@ -2784,10 +2787,9 @@ update_action(void *arg) {
|
|||
|
||||
INSIST(ssutable == NULL || maxidx < maxbytypelen);
|
||||
|
||||
get_current_rr(zoneclass, name, &rdata, &covers, &ttl,
|
||||
&update_class);
|
||||
get_current_rr(name, &rdata, &covers, &ttl, &update_class);
|
||||
|
||||
if (update_class == zoneclass) {
|
||||
if (update_class == dns_rdataclass_in) {
|
||||
/*
|
||||
* RFC1123 doesn't allow MF and MD in master files.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue