]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add a limit to the number of RR types for single name
authorOndřej Surý <ondrej@isc.org>
Wed, 29 May 2024 06:43:39 +0000 (08:43 +0200)
committerOndřej Surý <ondrej@isc.org>
Wed, 5 Jun 2024 07:02:14 +0000 (09:02 +0200)
Previously, the number of RR types for a single owner name was limited
only by the maximum number of the types (64k).  As the data structure
that holds the RR types for the database node is just a linked list, and
there are places where we just walk through the whole list (again and
again), adding a large number of RR types for a single owner named with
would slow down processing of such name (database node).

Add a hard-coded limit (100) to cap the number of the RR types for a single
owner.  The limit can be changed at the compile time by adding following
define to CFLAGS:

    -DDNS_RBTDB_MAX_RTYPES=<limit>

(cherry picked from commit 538b843d84f49ba5125ff545e3d0cf1c8434a8f2)

configure
configure.ac
lib/dns/rbtdb.c

index 76de61f49a775b5e1e9fb8850c0093f7e486d9d6..9174ad8e3527e6bb0ecb6a587d2b18298e90d402 100755 (executable)
--- a/configure
+++ b/configure
@@ -12185,7 +12185,7 @@ fi
 XTARGETS=
 case "$enable_developer" in
 yes)
-       STD_CDEFINES="$STD_CDEFINES -DISC_LIST_CHECKINIT=1 -DDNS_RDATASET_MAX_RECORDS=5000"
+       STD_CDEFINES="$STD_CDEFINES -DISC_LIST_CHECKINIT=1 -DDNS_RDATASET_MAX_RECORDS=5000 -DDNS_RBTDB_MAX_RTYPES=5000"
        test "${enable_fixed_rrset+set}" = set || enable_fixed_rrset=yes
        test "${enable_querytrace+set}" = set || enable_querytrace=yes
        test "${enable_filter_aaaa+set}" = set || enable_filter_aaaa=yes
index be37b9f6313a836dcf8641639ff2ee1831c44d4b..fdbc160a1ba2a895fcd65cfefd9b63dfc958bd3d 100644 (file)
@@ -100,7 +100,7 @@ AC_ARG_ENABLE(developer,
 XTARGETS=
 case "$enable_developer" in
 yes)
-       STD_CDEFINES="$STD_CDEFINES -DISC_LIST_CHECKINIT=1 -DDNS_RDATASET_MAX_RECORDS=5000"
+       STD_CDEFINES="$STD_CDEFINES -DISC_LIST_CHECKINIT=1 -DDNS_RDATASET_MAX_RECORDS=5000 -DDNS_RBTDB_MAX_RTYPES=5000"
        test "${enable_fixed_rrset+set}" = set || enable_fixed_rrset=yes
        test "${enable_querytrace+set}" = set || enable_querytrace=yes
        test "${enable_filter_aaaa+set}" = set || enable_filter_aaaa=yes
index abe2d9b49c3a2ebbbb6866545bfdbc53b459b0c8..c83d5dcf1dea7e8ac0b5267bf0d5853f27a8b420 100644 (file)
@@ -6200,6 +6200,10 @@ update_recordsandbytes(bool add, rbtdb_version_t *rbtversion,
        RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_write);
 }
 
+#ifndef DNS_RBTDB_MAX_RTYPES
+#define DNS_RBTDB_MAX_RTYPES 100
+#endif /* DNS_RBTDB_MAX_RTYPES */
+
 /*
  * write lock on rbtnode must be held.
  */
@@ -6220,6 +6224,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
        rbtdb_rdatatype_t negtype, sigtype;
        dns_trust_t trust;
        int idx;
+       uint32_t ntypes;
 
        /*
         * Add an rdatasetheader_t to a node.
@@ -6282,6 +6287,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                                        set_ttl(rbtdb, topheader, 0);
                                        mark_stale_header(rbtdb, topheader);
                                }
+                               ntypes = 0;
                                goto find_header;
                        }
                        /*
@@ -6303,9 +6309,11 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                         * check for an extant non-stale NODATA ncache
                         * entry which covers the same type as the RRSIG.
                         */
+                       ntypes = 0;
                        for (topheader = rbtnode->data;
                             topheader != NULL;
                             topheader = topheader->next) {
+                               ntypes++;
                                if ((topheader->type ==
                                        RBTDB_RDATATYPE_NCACHEANY) ||
                                        (newheader->type == sigtype &&
@@ -6349,9 +6357,11 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                }
        }
 
+       ntypes = 0;
        for (topheader = rbtnode->data;
             topheader != NULL;
             topheader = topheader->next) {
+               ntypes++;
                if (prio_type(topheader->type)) {
                        prioheader = topheader;
                }
@@ -6710,6 +6720,13 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                        /*
                         * No rdatasets of the given type exist at the node.
                         */
+
+                       if (ntypes > DNS_RBTDB_MAX_RTYPES) {
+                               free_rdataset(rbtdb, rbtdb->common.mctx,
+                                             newheader);
+                               return (ISC_R_QUOTA);
+                       }
+
                        newheader->down = NULL;
 
                        if (prio_type(newheader->type)) {