]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #841: big local-zone's make it consume large amounts of memory.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 29 Sep 2016 13:11:26 +0000 (13:11 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 29 Sep 2016 13:11:26 +0000 (13:11 +0000)
git-svn-id: file:///svn/unbound/trunk@3874 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
services/localzone.c

index 0602700d9a80dedbaa3e03f5fe05c37f2847bdeb..a5cbfe1a4f20e6494578482493dc462ea81eddac 100644 (file)
@@ -2,6 +2,7 @@
        - Fix #838: 1.5.10 cannot be built on Solaris, undefined PATH_MAX.
        - Fix #839: Memory grows unexpectedly with large RPZ files.
        - Fix #840: infinite loop in unbound_munin_ plugin on unowned lockfile.
+       - Fix #841: big local-zone's make it consume large amounts of memory.
 
 27 September 2016: Wouter
        - tag for 1.5.10 release
index 6446e3f2620540b4383dd7b09040a9643130bb36..01070f239e8a77cb4387890f0ed0c72e1a93d70b 100644 (file)
 #include "util/data/msgparse.h"
 #include "util/as112.h"
 
+/* maximum RRs in an RRset, to cap possible 'endless' list RRs.
+ * with 16 bytes for an A record, a 64K packet has about 4000 max */
+#define LOCALZONE_RRSET_COUNT_MAX 4096
+
 struct local_zones* 
 local_zones_create(void)
 {
@@ -342,13 +346,18 @@ new_local_rrset(struct regional* region, struct local_data* node,
 /** insert RR into RRset data structure; Wastes a couple of bytes */
 static int
 insert_rr(struct regional* region, struct packed_rrset_data* pd,
-       uint8_t* rdata, size_t rdata_len, time_t ttl)
+       uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr)
 {
        size_t* oldlen = pd->rr_len;
        time_t* oldttl = pd->rr_ttl;
        uint8_t** olddata = pd->rr_data;
 
        /* add RR to rrset */
+       if(pd->count > LOCALZONE_RRSET_COUNT_MAX) {
+               log_warn("RRset '%s' has more than %d records, record ignored",
+                       rrstr, LOCALZONE_RRSET_COUNT_MAX);
+               return 1;
+       }
        pd->count++;
        pd->rr_len = regional_alloc(region, sizeof(*pd->rr_len)*pd->count);
        pd->rr_ttl = regional_alloc(region, sizeof(*pd->rr_ttl)*pd->count);
@@ -479,7 +488,7 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
                verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr);
                return 1;
        } 
-       return insert_rr(z->region, pd, rdata, rdata_len, ttl);
+       return insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr);
 }
 
 /** enter a data RR into auth data; a zone for it must exist */