2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

Resolve violation of weak referencing dns_view

The dns_view implements weak and strong reference counting.  When strong
reference counting reaches zero, the adb, ntatable and resolver objects
are shut down and detached.

In dns_zone and dns_nta the dns_view was weakly attached, but the
view->resolver reference was accessed directly leading to dereferencing
the NULL pointer.

Add dns_view_getresolver() method which attaches to view->resolver
object under the lock (if it still exists) ensuring the dns_resolver
will be kept referenced until not needed.
This commit is contained in:
Ondřej Surý
2022-10-03 15:54:12 +02:00
committed by Evan Hunt
parent 934a6a8b8f
commit bff3025396
5 changed files with 116 additions and 49 deletions

View File

@@ -507,23 +507,46 @@ dns_view_detach(dns_view_t **viewp) {
if (isc_refcount_decrement(&view->references) == 1) {
dns_zone_t *mkzone = NULL, *rdzone = NULL;
dns_zt_t *zt = NULL;
dns_resolver_t *resolver = NULL;
dns_adb_t *adb = NULL;
dns_requestmgr_t *requestmgr = NULL;
isc_refcount_destroy(&view->references);
/* Swap the pointers under the lock */
LOCK(&view->lock);
if (view->resolver != NULL) {
dns_resolver_shutdown(view->resolver);
dns_resolver_detach(&view->resolver);
}
if (view->adb != NULL) {
dns_adb_shutdown(view->adb);
dns_adb_detach(&view->adb);
}
if (view->requestmgr != NULL) {
dns_requestmgr_shutdown(view->requestmgr);
dns_requestmgr_detach(&view->requestmgr);
resolver = view->resolver;
view->resolver = NULL;
UNLOCK(&view->lock);
dns_resolver_shutdown(resolver);
dns_resolver_detach(&resolver);
LOCK(&view->lock);
}
LOCK(&view->lock);
if (view->adb != NULL) {
adb = view->adb;
view->adb = NULL;
UNLOCK(&view->lock);
dns_adb_shutdown(adb);
dns_adb_detach(&adb);
LOCK(&view->lock);
}
if (view->requestmgr != NULL) {
requestmgr = view->requestmgr;
view->requestmgr = NULL;
UNLOCK(&view->lock);
dns_requestmgr_shutdown(requestmgr);
dns_requestmgr_detach(&requestmgr);
LOCK(&view->lock);
}
if (view->zonetable != NULL) {
zt = view->zonetable;
@@ -2396,3 +2419,19 @@ dns_view_sfd_find(dns_view_t *view, const dns_name_t *name,
dns_name_copy(dns_rootname, foundname);
}
}
isc_result_t
dns_view_getresolver(dns_view_t *view, dns_resolver_t **resolverp) {
isc_result_t result;
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(resolverp != NULL && *resolverp == NULL);
LOCK(&view->lock);
if (view->resolver != NULL) {
dns_resolver_attach(view->resolver, resolverp);
result = ISC_R_SUCCESS;
} else {
result = ISC_R_SHUTTINGDOWN;
}
UNLOCK(&view->lock);
return (result);
}