mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
[9.18] fix: usr: Reject record sets too large to serve in DNS
When BIND was asked to store a record set whose total size exceeds what fits in a DNS message, it would allocate memory and build the structure, then fail later at response time. Such oversized record sets are now rejected at the time of storage with an error, avoiding wasted work on data that can never be served. Backport of MR !11963 Merge branch 'backport-ondrej/harden-buflen-overflow-9.18' into 'bind-9.18' See merge request isc-projects/bind9!11965
This commit is contained in:
commit
ab3d96b3e3
2 changed files with 22 additions and 5 deletions
|
|
@ -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++;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue