]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
9.6.1-P2
authorMark Andrews <marka@isc.org>
Wed, 18 Nov 2009 23:58:04 +0000 (23:58 +0000)
committerMark Andrews <marka@isc.org>
Wed, 18 Nov 2009 23:58:04 +0000 (23:58 +0000)
CHANGES
bin/named/query.c
lib/dns/api
lib/dns/include/dns/types.h
lib/dns/masterdump.c
lib/dns/rbtdb.c
lib/dns/resolver.c
lib/dns/validator.c
version

diff --git a/CHANGES b/CHANGES
index 1f2c35a1411361c9a4df66a3bf1620ea8803aeef..fd065d0da2b6babdb5374eb988a28526dfd06781 100644 (file)
--- 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
index ffd9b3554a76c7c86d1f6025e57e4a4e6f4ea6d1..602948497a4f033d4eb617b047cd2b8f322011af 100644 (file)
@@ -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 */
 
 #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");
index af155ca8f5f094397eebb023361e199e30132090..4bcf883246ceb56d1ab730f0591efe94ee1b8f8a 100644 (file)
@@ -1,3 +1,3 @@
-LIBINTERFACE = 52
+LIBINTERFACE = 53
 LIBREVISION = 0
-LIBAGE = 2
+LIBAGE = 0
index e07a7965bffb475bb85085b48918260f9092f5ab..8c7773c3160f4031065a9995f987429ea08f63c0 100644 (file)
@@ -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.
  */
index 5eac96ff28075bc52343042cf6e0f0ed9a8e832e..1dbb1e615e8b6b59887177ca72b5db0463865d99 100644 (file)
@@ -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",
index 9741c157f7840e2691ef635a590754004a63a546..b163441d43bd04e4930282fceae394c0fd8b3db8 100644 (file)
@@ -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
index a5d7c2500f8fa6d37f76c409d9d3e0d886e8cd51..3b90af4400c32710046f82b7599a43f2ddf9bad0 100644 (file)
@@ -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);
                }
index c62b714162bae7ab04ff4efe36d283ff83889126..46a74919c825a2944422b03a36e70d8b7a31ca8b 100644 (file)
@@ -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 3245f02d3fd8d97cce84e3b4c45c681a4e5f02ad..ccb7b87efb2c7be6d591bfac0fdce521e1a9e647 100644 (file)
--- 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