diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index 9a652076a7..2afb5ad7c9 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -126,7 +126,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, #if DNS_RDATASET_FIXED unsigned char *offsetbase; #endif /* if DNS_RDATASET_FIXED */ - unsigned int buflen; + uint32_t buflen; isc_result_t result; unsigned int nitems; unsigned int nalloc; @@ -240,6 +240,10 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, if (rdataset->type == dns_rdatatype_rrsig) { buflen++; } + if (buflen - reservelen - 2 > DNS_RDATA_MAXLENGTH) { + result = ISC_R_NOSPACE; + goto free_rdatas; + } } } @@ -257,6 +261,10 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, if (rdataset->type == dns_rdatatype_rrsig) { buflen++; } + if (buflen - reservelen - 2 > DNS_RDATA_MAXLENGTH) { + result = ISC_R_NOSPACE; + goto free_rdatas; + } /* * Ensure that singleton types are actually singletons. @@ -492,7 +500,8 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, unsigned int flags, uint32_t maxrrperset, unsigned char **tslabp) { unsigned char *ocurrent, *ostart, *ncurrent, *tstart, *tcurrent, *data; - unsigned int ocount, ncount, count, olength, tlength, tcount, length; + unsigned int ocount, ncount, count, olength, tcount, length; + uint32_t tlength; dns_rdata_t ordata = DNS_RDATA_INIT; dns_rdata_t nrdata = DNS_RDATA_INIT; bool added_something = false; @@ -583,6 +592,9 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, if (type == dns_rdatatype_rrsig) { tlength++; } + if (tlength - reservelen - 2 > DNS_RDATA_MAXLENGTH) { + return ISC_R_NOSPACE; + } tcount++; nncount++; added_something = true; @@ -761,7 +773,8 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, dns_rdataclass_t rdclass, dns_rdatatype_t type, unsigned int flags, unsigned char **tslabp) { unsigned char *mcurrent, *sstart, *scurrent, *tstart, *tcurrent; - unsigned int mcount, scount, rcount, count, tlength, tcount, i; + unsigned int mcount, scount, rcount, count, tcount, i; + uint32_t tlength; dns_rdata_t srdata = DNS_RDATA_INIT; dns_rdata_t mrdata = DNS_RDATA_INIT; #if DNS_RDATASET_FIXED @@ -818,7 +831,10 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, * This rdata isn't in the sslab, and thus isn't * being subtracted. */ - tlength += (unsigned int)(mcurrent - mrdatabegin); + tlength += (uint32_t)(mcurrent - mrdatabegin); + if (tlength - reservelen - 2 > DNS_RDATA_MAXLENGTH) { + return ISC_R_NOSPACE; + } tcount++; } else { rcount++; diff --git a/tests/dns/rbtdb_test.c b/tests/dns/rbtdb_test.c index a06e4a1ad0..cfc2a5779b 100644 --- a/tests/dns/rbtdb_test.c +++ b/tests/dns/rbtdb_test.c @@ -316,7 +316,8 @@ ISC_RUN_TEST_IMPL(overmempurge_bigrdata) { * cache size doesn't reach the "max". */ while (i-- > 0) { - overmempurge_addrdataset(db, now, i, 50054, 65535, false); + overmempurge_addrdataset(db, now, i, 50054, + DNS_RDATA_MAXLENGTH - 8, false); assert_true(isc_mem_inuse(mctx2) < maxcache); }