aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Barton <dougb@FreeBSD.org>2009-11-30 02:59:30 +0000
committerDoug Barton <dougb@FreeBSD.org>2009-11-30 02:59:30 +0000
commit0f784036a584bfffbf0758a1d1664f605924c014 (patch)
tree37ffd545adce0dc8679de1224253dec1127a85e6
parentd5e9ae7e174c2efbbf724c173aa324efe94b7ccc (diff)
downloadsrc-0f784036a584bfffbf0758a1d1664f605924c014.tar.gz
src-0f784036a584bfffbf0758a1d1664f605924c014.zip
Vendor import of BIND 9.6.1-P2vendor/bind9/9.6.1-P2
Notes
Notes: svn path=/vendor/bind9/dist/; revision=199956 svn path=/vendor/bind9/9.6.1-P2/; revision=199957; tag=vendor/bind9/9.6.1-P2
-rw-r--r--CHANGES6
-rw-r--r--bin/named/query.c68
-rw-r--r--lib/dns/api4
-rw-r--r--lib/dns/include/dns/types.h34
-rw-r--r--lib/dns/masterdump.c5
-rw-r--r--lib/dns/rbtdb.c6
-rw-r--r--lib/dns/resolver.c33
-rw-r--r--lib/dns/validator.c12
-rw-r--r--version4
9 files changed, 129 insertions, 43 deletions
diff --git a/CHANGES b/CHANGES
index 1f2c35a14113..fd065d0da2b6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+ --- 9.6.1-P2 released ---
+
+2772. [security] When validating, track whether pending data was from
+ the additional section or not and only return it if
+ validates as secure. [RT #20438]
+
--- 9.6.1-P1 released ---
2640. [security] A specially crafted update packet will cause named
diff --git a/bin/named/query.c b/bin/named/query.c
index ffd9b3554a76..602948497a4f 100644
--- a/bin/named/query.c
+++ b/bin/named/query.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.c,v 1.313.20.7 2009/03/13 01:38:51 marka Exp $ */
+/* $Id: query.c,v 1.313.20.7.12.1 2009/11/18 23:58:04 marka Exp $ */
/*! \file */
@@ -116,6 +116,8 @@
#define DNS_GETDB_NOLOG 0x02U
#define DNS_GETDB_PARTIAL 0x04U
+#define PENDINGOK(x) (((x) & DNS_DBFIND_PENDINGOK) != 0)
+
typedef struct client_additionalctx {
ns_client_t *client;
dns_rdataset_t *rdataset;
@@ -1761,8 +1763,8 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
*/
if (result == ISC_R_SUCCESS &&
additionaltype == dns_rdatasetadditional_fromcache &&
- (rdataset->trust == dns_trust_pending ||
- rdataset->trust == dns_trust_glue) &&
+ (DNS_TRUST_PENDING(rdataset->trust) ||
+ DNS_TRUST_GLUE(rdataset->trust)) &&
!validate(client, db, fname, rdataset, sigrdataset)) {
dns_rdataset_disassociate(rdataset);
if (dns_rdataset_isassociated(sigrdataset))
@@ -1801,8 +1803,8 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
*/
if (result == ISC_R_SUCCESS &&
additionaltype == dns_rdatasetadditional_fromcache &&
- (rdataset->trust == dns_trust_pending ||
- rdataset->trust == dns_trust_glue) &&
+ (DNS_TRUST_PENDING(rdataset->trust) ||
+ DNS_TRUST_GLUE(rdataset->trust)) &&
!validate(client, db, fname, rdataset, sigrdataset)) {
dns_rdataset_disassociate(rdataset);
if (dns_rdataset_isassociated(sigrdataset))
@@ -2601,14 +2603,14 @@ query_addbestns(ns_client_t *client) {
/*
* Attempt to validate RRsets that are pending or that are glue.
*/
- if ((rdataset->trust == dns_trust_pending ||
- (sigrdataset != NULL && sigrdataset->trust == dns_trust_pending))
+ if ((DNS_TRUST_PENDING(rdataset->trust) ||
+ (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust)))
&& !validate(client, db, fname, rdataset, sigrdataset) &&
- (client->query.dboptions & DNS_DBFIND_PENDINGOK) == 0)
+ !PENDINGOK(client->query.dboptions))
goto cleanup;
- if ((rdataset->trust == dns_trust_glue ||
- (sigrdataset != NULL && sigrdataset->trust == dns_trust_glue)) &&
+ if ((DNS_TRUST_GLUE(rdataset->trust) ||
+ (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) &&
!validate(client, db, fname, rdataset, sigrdataset) &&
SECURE(client) && WANTDNSSEC(client))
goto cleanup;
@@ -3716,6 +3718,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_rdataset_t *noqname;
isc_boolean_t resuming;
int line = -1;
+ dns_rdataset_t tmprdataset;
+ unsigned int dboptions;
CTRACE("query_find");
@@ -3933,9 +3937,49 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
/*
* Now look for an answer in the database.
*/
+ dboptions = client->query.dboptions;
+ if (sigrdataset == NULL && client->view->enablednssec) {
+ /*
+ * If the client doesn't want DNSSEC we still want to
+ * look for any data pending validation to save a remote
+ * lookup if possible.
+ */
+ dns_rdataset_init(&tmprdataset);
+ sigrdataset = &tmprdataset;
+ dboptions |= DNS_DBFIND_PENDINGOK;
+ }
+ refind:
result = dns_db_find(db, client->query.qname, version, type,
- client->query.dboptions, client->now,
- &node, fname, rdataset, sigrdataset);
+ dboptions, client->now, &node, fname,
+ rdataset, sigrdataset);
+ /*
+ * If we have found pending data try to validate it.
+ * If the data does not validate as secure and we can't
+ * use the unvalidated data requery the database with
+ * pending disabled to prevent infinite looping.
+ */
+ if (result != ISC_R_SUCCESS || !DNS_TRUST_PENDING(rdataset->trust))
+ goto validation_done;
+ if (validate(client, db, fname, rdataset, sigrdataset))
+ goto validation_done;
+ if (rdataset->trust != dns_trust_pending_answer ||
+ !PENDINGOK(client->query.dboptions)) {
+ dns_rdataset_disassociate(rdataset);
+ if (sigrdataset != NULL &&
+ dns_rdataset_isassociated(sigrdataset))
+ dns_rdataset_disassociate(sigrdataset);
+ if (sigrdataset == &tmprdataset)
+ sigrdataset = NULL;
+ dns_db_detachnode(db, &node);
+ dboptions &= ~DNS_DBFIND_PENDINGOK;
+ goto refind;
+ }
+ validation_done:
+ if (sigrdataset == &tmprdataset) {
+ if (dns_rdataset_isassociated(sigrdataset))
+ dns_rdataset_disassociate(sigrdataset);
+ sigrdataset = NULL;
+ }
resume:
CTRACE("query_find: resume");
diff --git a/lib/dns/api b/lib/dns/api
index af155ca8f5f0..4bcf883246ce 100644
--- a/lib/dns/api
+++ b/lib/dns/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 52
+LIBINTERFACE = 53
LIBREVISION = 0
-LIBAGE = 2
+LIBAGE = 0
diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h
index e07a7965bffb..8c7773c3160f 100644
--- a/lib/dns/include/dns/types.h
+++ b/lib/dns/include/dns/types.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.130.50.3 2009/01/29 22:40:35 jinmei Exp $ */
+/* $Id: types.h,v 1.130.50.3.12.1 2009/11/18 23:58:04 marka Exp $ */
#ifndef DNS_TYPES_H
#define DNS_TYPES_H 1
@@ -258,40 +258,52 @@ enum {
dns_trust_none = 0,
#define dns_trust_none ((dns_trust_t)dns_trust_none)
- /*% Subject to DNSSEC validation but has not yet been validated */
- dns_trust_pending = 1,
-#define dns_trust_pending ((dns_trust_t)dns_trust_pending)
+ /*%
+ * Subject to DNSSEC validation but has not yet been validated
+ * dns_trust_pending_additional (from the additional section).
+ */
+ dns_trust_pending_additional = 1,
+#define dns_trust_pending_additional \
+ ((dns_trust_t)dns_trust_pending_additional)
+
+ dns_trust_pending_answer = 2,
+#define dns_trust_pending_answer ((dns_trust_t)dns_trust_pending_answer)
/*% Received in the additional section of a response. */
- dns_trust_additional = 2,
+ dns_trust_additional = 3,
#define dns_trust_additional ((dns_trust_t)dns_trust_additional)
/* Received in a referral response. */
- dns_trust_glue = 3,
+ dns_trust_glue = 4,
#define dns_trust_glue ((dns_trust_t)dns_trust_glue)
/* Answer from a non-authoritative server */
- dns_trust_answer = 4,
+ dns_trust_answer = 5,
#define dns_trust_answer ((dns_trust_t)dns_trust_answer)
/* Received in the authority section as part of an
authoritative response */
- dns_trust_authauthority = 5,
+ dns_trust_authauthority = 6,
#define dns_trust_authauthority ((dns_trust_t)dns_trust_authauthority)
/* Answer from an authoritative server */
- dns_trust_authanswer = 6,
+ dns_trust_authanswer = 7,
#define dns_trust_authanswer ((dns_trust_t)dns_trust_authanswer)
/* Successfully DNSSEC validated */
- dns_trust_secure = 7,
+ dns_trust_secure = 8,
#define dns_trust_secure ((dns_trust_t)dns_trust_secure)
/* This server is authoritative */
- dns_trust_ultimate = 8
+ dns_trust_ultimate = 9
#define dns_trust_ultimate ((dns_trust_t)dns_trust_ultimate)
};
+#define DNS_TRUST_PENDING(x) ((x) == dns_trust_pending_answer || \
+ (x) == dns_trust_pending_additional)
+#define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue)
+
+
/*%
* Name checking severities.
*/
diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c
index 5eac96ff2807..1dbb1e615e8b 100644
--- a/lib/dns/masterdump.c
+++ b/lib/dns/masterdump.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: masterdump.c,v 1.94.50.2 2009/01/18 23:47:40 tbox Exp $ */
+/* $Id: masterdump.c,v 1.94.50.2.12.1 2009/11/18 23:58:04 marka Exp $ */
/*! \file */
@@ -775,7 +775,8 @@ dump_order_compare(const void *a, const void *b) {
static const char *trustnames[] = {
"none",
- "pending",
+ "pending-additional",
+ "pending-answer",
"additional",
"glue",
"answer",
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 9741c157f784..b163441d43bd 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.270.12.6 2009/05/06 23:34:30 jinmei Exp $ */
+/* $Id: rbtdb.c,v 1.270.12.6.10.1 2009/11/18 23:58:04 marka Exp $ */
/*! \file */
@@ -4005,7 +4005,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
}
if (dname_header != NULL &&
- (dname_header->trust != dns_trust_pending ||
+ (!DNS_TRUST_PENDING(dname_header->trust) ||
(search->options & DNS_DBFIND_PENDINGOK) != 0)) {
/*
* We increment the reference count on node to ensure that
@@ -4548,7 +4548,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
if (found == NULL ||
(found->trust == dns_trust_glue &&
((options & DNS_DBFIND_GLUEOK) == 0)) ||
- (found->trust == dns_trust_pending &&
+ (DNS_TRUST_PENDING(found->trust) &&
((options & DNS_DBFIND_PENDINGOK) == 0))) {
/*
* If there is an NS rdataset at this node, then this is the
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index a5d7c2500f8f..3b90af4400c3 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.384.14.14 2009/06/02 23:47:13 tbox Exp $ */
+/* $Id: resolver.c,v 1.384.14.14.8.1 2009/11/18 23:58:04 marka Exp $ */
/*! \file */
@@ -4293,6 +4293,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
* for it, unless it is glue.
*/
if (secure_domain && rdataset->trust != dns_trust_glue) {
+ dns_trust_t trust;
/*
* RRSIGs are validated as part of validating the
* type they cover.
@@ -4329,12 +4330,34 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
}
/*
+ * Reject out of bailiwick additional records
+ * without RRSIGs as they can't possibly validate
+ * as "secure" and as we will never never want to
+ * store these as "answers" after validation.
+ */
+ if (rdataset->trust == dns_trust_additional &&
+ sigrdataset == NULL && EXTERNAL(rdataset))
+ continue;
+
+ /*
+ * XXXMPA: If we store as "answer" after validating
+ * then we need to do bailiwick processing and
+ * also need to track whether RRsets are in or
+ * out of bailiwick. This will require a another
+ * pending trust level.
+ *
* Cache this rdataset/sigrdataset pair as
- * pending data.
+ * pending data. Track whether it was additional
+ * or not.
*/
- rdataset->trust = dns_trust_pending;
+ if (rdataset->trust == dns_trust_additional)
+ trust = dns_trust_pending_additional;
+ else
+ trust = dns_trust_pending_answer;
+
+ rdataset->trust = trust;
if (sigrdataset != NULL)
- sigrdataset->trust = dns_trust_pending;
+ sigrdataset->trust = trust;
if (!need_validation || !ANSWER(rdataset)) {
addedrdataset = ardataset;
result = dns_db_addrdataset(fctx->cache, node,
@@ -4682,7 +4705,7 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
for (trdataset = ISC_LIST_HEAD(tname->list);
trdataset != NULL;
trdataset = ISC_LIST_NEXT(trdataset, link))
- trdataset->trust = dns_trust_pending;
+ trdataset->trust = dns_trust_pending_answer;
result = dns_message_nextname(fctx->rmessage,
DNS_SECTION_AUTHORITY);
}
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index c62b714162ba..46a74919c825 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.c,v 1.164.12.9 2009/05/07 23:47:12 tbox Exp $ */
+/* $Id: validator.c,v 1.164.12.9.8.1 2009/11/18 23:58:04 marka Exp $ */
#include <config.h>
@@ -1607,7 +1607,7 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
* We have an rrset for the given keyname.
*/
val->keyset = &val->frdataset;
- if (val->frdataset.trust == dns_trust_pending &&
+ if (DNS_TRUST_PENDING(val->frdataset.trust) &&
dns_rdataset_isassociated(&val->fsigrdataset))
{
/*
@@ -1622,7 +1622,7 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
if (result != ISC_R_SUCCESS)
return (result);
return (DNS_R_WAIT);
- } else if (val->frdataset.trust == dns_trust_pending) {
+ } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
/*
* Having a pending key with no signature means that
* something is broken.
@@ -2243,7 +2243,7 @@ validatezonekey(dns_validator_t *val) {
* We have DS records.
*/
val->dsset = &val->frdataset;
- if (val->frdataset.trust == dns_trust_pending &&
+ if (DNS_TRUST_PENDING(val->frdataset.trust) &&
dns_rdataset_isassociated(&val->fsigrdataset))
{
result = create_validator(val,
@@ -2256,7 +2256,7 @@ validatezonekey(dns_validator_t *val) {
if (result != ISC_R_SUCCESS)
return (result);
return (DNS_R_WAIT);
- } else if (val->frdataset.trust == dns_trust_pending) {
+ } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
/*
* There should never be an unsigned DS.
*/
@@ -3337,7 +3337,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
* There is no DS. If this is a delegation,
* we maybe done.
*/
- if (val->frdataset.trust == dns_trust_pending) {
+ if (DNS_TRUST_PENDING(val->frdataset.trust)) {
result = create_fetch(val, tname,
dns_rdatatype_ds,
dsfetched2,
diff --git a/version b/version
index 3245f02d3fd8..ccb7b87efb2c 100644
--- a/version
+++ b/version
@@ -1,4 +1,4 @@
-# $Id: version,v 1.43.12.5.8.1 2009/07/28 14:18:08 marka Exp $
+# $Id: version,v 1.43.12.5.8.2 2009/11/18 23:58:04 marka Exp $
#
# This file must follow /bin/sh rules. It is imported directly via
# configure.
@@ -7,4 +7,4 @@ MAJORVER=9
MINORVER=6
PATCHVER=1
RELEASETYPE=-P
-RELEASEVER=1
+RELEASEVER=2