bind9+unbound: 5-MOAD scan; 2 defects (bind9-0001 CWE-407 zone_registerinclude O(N^2), unbound-0001 CWE-407 rdata_duplicate O(R^2))
This commit is contained in:
parent
d9d4b30def
commit
3aae5093e5
6 changed files with 488 additions and 0 deletions
|
|
@ -0,0 +1,79 @@
|
|||
# UNDF:
|
||||
--- a/lib/dns/zone.c
|
||||
+++ b/lib/dns/zone.c
|
||||
@@ -302,6 +302,7 @@ struct dns_zone {
|
||||
const FILE *stream; /* loading from a stream? */
|
||||
ISC_LIST(dns_include_t) includes; /* Include files */
|
||||
ISC_LIST(dns_include_t) newincludes; /* Loading */
|
||||
+ isc_ht_t *newincludes_ht; /* O(1) dup-check during loading */
|
||||
unsigned int nincludes;
|
||||
|
||||
@@ -1165,6 +1166,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, isc_loopmgr_t *loopmgr) {
|
||||
.includes = ISC_LIST_INITIALIZER,
|
||||
.newincludes = ISC_LIST_INITIALIZER,
|
||||
+ .newincludes_ht = NULL,
|
||||
.nincludes = 0,
|
||||
|
||||
@@ -2703,6 +2704,26 @@ zone_registerinclude(const char *filename, void *arg) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
if (filename == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * On first call, create a hash table for O(1) duplicate detection.
|
||||
+ * Without this, the ISC_LIST_FOREACH scan below is O(N) per call,
|
||||
+ * making the total zone-load cost O(N^2) in the number of $INCLUDE
|
||||
+ * directives. CWE-407.
|
||||
+ */
|
||||
+ if (zone->newincludes_ht == NULL) {
|
||||
+ isc_ht_init(&zone->newincludes_ht, zone->mctx, 4,
|
||||
+ ISC_HT_CASE_SENSITIVE);
|
||||
+ }
|
||||
+
|
||||
+ if (zone->newincludes_ht != NULL) {
|
||||
+ void *found = NULL;
|
||||
+ uint32_t flen = (uint32_t)strlen(filename);
|
||||
+ if (isc_ht_find(zone->newincludes_ht,
|
||||
+ (const unsigned char *)filename, flen,
|
||||
+ &found) == ISC_R_SUCCESS) {
|
||||
+ return; /* duplicate */
|
||||
+ }
|
||||
/*
|
||||
* Suppress duplicates.
|
||||
- */
|
||||
- ISC_LIST_FOREACH (zone->newincludes, inc, link) {
|
||||
- if (strcmp(filename, inc->name) == 0) {
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
+ * (keep list append below; list is still needed for iteration) */
|
||||
+ }
|
||||
|
||||
dns_include_t *inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
|
||||
inc->name = isc_mem_strdup(zone->mctx, filename);
|
||||
@@ -2730,6 +2751,12 @@ zone_registerinclude(const char *filename, void *arg) {
|
||||
isc_time_settoepoch(&inc->filetime);
|
||||
}
|
||||
|
||||
+ if (zone->newincludes_ht != NULL) {
|
||||
+ uint32_t flen = (uint32_t)strlen(filename);
|
||||
+ (void)isc_ht_add(zone->newincludes_ht,
|
||||
+ (const unsigned char *)inc->name, flen, inc);
|
||||
+ }
|
||||
+
|
||||
ISC_LIST_APPEND(zone->newincludes, inc, link);
|
||||
}
|
||||
|
||||
@@ -5695,6 +5722,11 @@ zone_loaddone(void *arg, isc_result_t result) {
|
||||
ISC_LIST_FOREACH (zone->includes, inc, link) {
|
||||
ISC_LIST_UNLINK(zone->includes, inc, link);
|
||||
...
|
||||
+ if (zone->newincludes_ht != NULL) {
|
||||
+ isc_ht_destroy(&zone->newincludes_ht);
|
||||
+ zone->newincludes_ht = NULL;
|
||||
+ }
|
||||
+
|
||||
zone->nincludes = 0;
|
||||
ISC_LIST_FOREACH (zone->newincludes, inc, link) {
|
||||
Loading…
Add table
Add a link
Reference in a new issue