]> 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)
committerNicki Křížek <nicki@isc.org>
Wed, 24 Jul 2024 08:56:59 +0000 (10:56 +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>

configure
configure.ac
lib/dns/rbtdb.c

index 30e65f1568ddbc5fd6068810a9709366108bb5ea..835cd94dff7ec600e7f673c18d71c8e045397f29 100755 (executable)
--- a/configure
+++ b/configure
@@ -12341,7 +12341,7 @@ fi
 
 XTARGETS=
 if test "$enable_developer" = "yes"; then :
-  STD_CDEFINES="$STD_CDEFINES -DISC_MEM_DEFAULTFILL=1 -DISC_LIST_CHECKINIT=1 -DDNS_RDATASET_MAX_RECORDS=5000"
+  STD_CDEFINES="$STD_CDEFINES -DISC_MEM_DEFAULTFILL=1 -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 "${with_cmocka+set}" = set || with_cmocka=yes
index ffe087e6d7b16b7aa75edfe3b92d912b15a1f9a3..6db42501a24fee6e781e07fce712d10a26e5bea1 100644 (file)
@@ -96,7 +96,7 @@ AC_ARG_ENABLE([developer],
 
 XTARGETS=
 AS_IF([test "$enable_developer" = "yes"],
-      [STD_CDEFINES="$STD_CDEFINES -DISC_MEM_DEFAULTFILL=1 -DISC_LIST_CHECKINIT=1 -DDNS_RDATASET_MAX_RECORDS=5000"
+      [STD_CDEFINES="$STD_CDEFINES -DISC_MEM_DEFAULTFILL=1 -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 "${with_cmocka+set}" = set || with_cmocka=yes
index 3f06545aa1eab5d8da11f0b12a4694747052fd8d..b35e101b016475d30dda74bbfb1bd48533f2d277 100644 (file)
@@ -6240,6 +6240,10 @@ update_recordsandxfrsize(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.
  */
@@ -6261,6 +6265,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
        rbtdb_rdatatype_t negtype, sigtype;
        dns_trust_t trust;
        int idx;
+       uint32_t ntypes;
 
        /*
         * Add an rdatasetheader_t to a node.
@@ -6325,6 +6330,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
                                        set_ttl(rbtdb, topheader, 0);
                                        mark_header_ancient(rbtdb, topheader);
                                }
+                               ntypes = 0;
                                goto find_header;
                        }
                        /*
@@ -6348,9 +6354,11 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
                         * check for an extant non-ancient 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 &&
@@ -6395,9 +6403,11 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
                }
        }
 
+       ntypes = 0;
        for (topheader = rbtnode->data; topheader != NULL;
             topheader = topheader->next)
        {
+               ntypes++;
                if (prio_type(topheader->type)) {
                        prioheader = topheader;
                }
@@ -6755,6 +6765,13 @@ find_header:
                        /*
                         * 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)) {