From dfcadc2085c8844b5836aff2b5ea51fb60c34868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 29 May 2024 08:43:39 +0200 Subject: [PATCH 2/3] Add a limit to the number of RR types for single name 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= Conflict:Context Adaptation Reference:https://gitlab.isc.org/isc-projects/bind9/-/commit/5360c90612abf51deb4a80b30e1da84fd61212a5 --- bind/bind-9.11.36/configure | 2 +- bind/bind-9.11.36/configure.ac | 2 +- bind/bind-9.11.36/lib/dns/rbtdb.c | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/bind/bind-9.11.36/configure b/bind/bind-9.11.36/configure index 736ff49..8e881e3 100755 --- a/bind/bind-9.11.36/configure +++ b/bind/bind-9.11.36/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 diff --git a/bind/bind-9.11.36/configure.ac b/bind/bind-9.11.36/configure.ac index cc36b6c..0eab441 100644 --- a/bind/bind-9.11.36/configure.ac +++ b/bind/bind-9.11.36/configure.ac @@ -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 diff --git a/bind/bind-9.11.36/lib/dns/rbtdb.c b/bind/bind-9.11.36/lib/dns/rbtdb.c index 3d76ca1..0cfef36 100644 --- a/bind/bind-9.11.36/lib/dns/rbtdb.c +++ b/bind/bind-9.11.36/lib/dns/rbtdb.c @@ -6190,6 +6190,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. */ @@ -6210,6 +6214,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. @@ -6272,6 +6277,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; } /* @@ -6293,9 +6299,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 && @@ -6339,9 +6347,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; } @@ -6700,6 +6710,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)) { -- 2.33.0