diff --git a/CHANGES b/CHANGES index 1cf1596d54..819ccb008b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +4289. [bug] The server could crash due to memory being used + after it was freed if a zone transfer timed out. + [RT #41297] + 4288. [bug] Fixed a regression in resolver.c:possibly_mark() which caused known-bogus servers to be queried anyway. [RT #41321] diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index dd39b47d47..1d042634ea 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -759,6 +759,12 @@
Bug Fixes + + + The server could crash due to a use-after-free if a + zone transfer timed out. [RT #41297] + + Authoritative servers that were marked as bogus (e.g. blackholed diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index e5faf921c5..5546104a29 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -346,8 +346,9 @@ dst_context_create4(dst_key_t *key, isc_mem_t *mctx, dctx = isc_mem_get(mctx, sizeof(dst_context_t)); if (dctx == NULL) return (ISC_R_NOMEMORY); - dctx->key = key; - dctx->mctx = mctx; + memset(dctx, 0, sizeof(*dctx)); + dst_key_attach(key, &dctx->key); + isc_mem_attach(mctx, &dctx->mctx); dctx->category = category; if (useforsigning) dctx->use = DO_SIGN; @@ -358,7 +359,9 @@ dst_context_create4(dst_key_t *key, isc_mem_t *mctx, else result = key->func->createctx(key, dctx); if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, dctx, sizeof(dst_context_t)); + if (dctx->key != NULL) + dst_key_free(&dctx->key); + isc_mem_putanddetach(&dctx->mctx, dctx, sizeof(dst_context_t)); return (result); } dctx->magic = CTX_MAGIC; @@ -375,8 +378,10 @@ dst_context_destroy(dst_context_t **dctxp) { dctx = *dctxp; INSIST(dctx->key->func->destroyctx != NULL); dctx->key->func->destroyctx(dctx); + if (dctx->key != NULL) + dst_key_free(&dctx->key); dctx->magic = 0; - isc_mem_put(dctx->mctx, dctx, sizeof(dst_context_t)); + isc_mem_putanddetach(&dctx->mctx, dctx, sizeof(dst_context_t)); *dctxp = NULL; }