]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Check the synth-form-dnssec namespace when synthesising responses
authorMark Andrews <marka@isc.org>
Thu, 16 Jun 2022 06:48:42 +0000 (16:48 +1000)
committerMark Andrews <marka@isc.org>
Wed, 6 Jul 2022 21:47:45 +0000 (07:47 +1000)
Call dns_view_sfd_find to find the namespace to be used to verify
the covering NSEC records returned for the given QNAME.  Check that
the NSEC owner names are within that namespace.

(cherry picked from commit 228dadb0268e5c6982975214c41594df05db2157)

lib/ns/query.c

index eb2b44b70ca6ca140adaef984018102e01203e4b..18ab138b1c959e04b91c1017db9c693dae4fabdf 100644 (file)
@@ -47,6 +47,7 @@
 #include <dns/nsec.h>
 #include <dns/nsec3.h>
 #include <dns/order.h>
+#include <dns/rbt.h>
 #include <dns/rdata.h>
 #include <dns/rdataclass.h>
 #include <dns/rdatalist.h>
@@ -10082,13 +10083,16 @@ query_coveringnsec(query_ctx_t *qctx) {
        dns_clientinfomethods_t cm;
        dns_dbnode_t *node = NULL;
        dns_fixedname_t fixed;
+       dns_fixedname_t fnamespace;
        dns_fixedname_t fnowild;
        dns_fixedname_t fsigner;
        dns_fixedname_t fwild;
        dns_name_t *fname = NULL;
+       dns_name_t *namespace = NULL;
        dns_name_t *nowild = NULL;
        dns_name_t *signer = NULL;
        dns_name_t *wild = NULL;
+       dns_name_t qname;
        dns_rdataset_t *soardataset = NULL, *sigsoardataset = NULL;
        dns_rdataset_t rdataset, sigrdataset;
        bool done = false;
@@ -10096,11 +10100,29 @@ query_coveringnsec(query_ctx_t *qctx) {
        bool redirected = false;
        isc_result_t result = ISC_R_SUCCESS;
        unsigned int dboptions = qctx->client->query.dboptions;
+       unsigned int labels;
 
        CCTRACE(ISC_LOG_DEBUG(3), "query_coveringnsec");
 
+       dns_name_init(&qname, NULL);
        dns_rdataset_init(&rdataset);
        dns_rdataset_init(&sigrdataset);
+       namespace = dns_fixedname_initname(&fnamespace);
+
+       /*
+        * Check that the NSEC record is from the correct namespace.
+        * For records that belong to the parent zone (i.e. DS),
+        * remove a label to find the correct namespace.
+        */
+       dns_name_clone(qctx->client->query.qname, &qname);
+       labels = dns_name_countlabels(&qname);
+       if (dns_rdatatype_atparent(qctx->qtype) && labels > 1) {
+               dns_name_getlabelsequence(&qname, 1, labels - 1, &qname);
+       }
+       dns_view_sfd_find(qctx->view, &qname, namespace);
+       if (!dns_name_issubdomain(qctx->fname, namespace)) {
+               goto cleanup;
+       }
 
        /*
         * If we have no signer name, stop immediately.
@@ -10230,6 +10252,13 @@ query_coveringnsec(query_ctx_t *qctx) {
 
        switch (result) {
        case DNS_R_COVERINGNSEC:
+               /*
+                * Check that the covering NSEC record is from the right
+                * namespace.
+                */
+               if (!dns_name_issubdomain(nowild, namespace)) {
+                       goto cleanup;
+               }
                result = dns_nsec_noexistnodata(qctx->qtype, wild, nowild,
                                                &rdataset, &exists, &data, NULL,
                                                log_noexistnodata, qctx);