Fix an interfacemgr use-after-free error in zoneconf.c:isself()

The 'named_g_server->interfacemgr' pointer is saved in the zone
structure using dns_zone_setisself(), as a void* argument to be
passed to the isself() callback, so there is no attach/detach,
and when shutting down, the interface manager can be destroyed
by the shutdown_server(), running in exclusive mode, and causing
isself() to crash when trying to use the pointer.

Instead of keeping the interface manager pointer in the zone
structure, just check and use the 'named_g_server->interfacemgr'
itself, as it was implemented originally in the
3aca8e5bf3 commit. Later, in the
8eb88aafee commit, the code was
changed to pass the interface manager pointer using the additional
void* argument, but the commit message doesn't mention if there
was any practical reason for that.

Additionally, don't pass the interfacemgr pointer to the
ns_interfacemgr_getaclenv() function before it is checked
against NULL.

(cherry picked from commit 64d69e4adc)
This commit is contained in:
Aram Sargsyan 2023-05-24 14:26:04 +00:00
parent 66254cf56d
commit 1d736cf451

View file

@ -777,23 +777,27 @@ checknames(dns_zonetype_t ztype, const cfg_obj_t **maps,
static bool
isself(dns_view_t *myview, dns_tsigkey_t *mykey, const isc_sockaddr_t *srcaddr,
const isc_sockaddr_t *dstaddr, dns_rdataclass_t rdclass, void *arg) {
ns_interfacemgr_t *interfacemgr = (ns_interfacemgr_t *)arg;
dns_aclenv_t *env = ns_interfacemgr_getaclenv(interfacemgr);
dns_view_t *view;
dns_aclenv_t *env = NULL;
dns_view_t *view = NULL;
dns_tsigkey_t *key = NULL;
isc_netaddr_t netsrc;
isc_netaddr_t netdst;
if (interfacemgr == NULL) {
UNUSED(arg);
/* interfacemgr can be destroyed only in exclusive mode. */
if (named_g_server->interfacemgr == NULL) {
return (true);
}
if (!ns_interfacemgr_listeningon(interfacemgr, dstaddr)) {
if (!ns_interfacemgr_listeningon(named_g_server->interfacemgr, dstaddr))
{
return (false);
}
isc_netaddr_fromsockaddr(&netsrc, srcaddr);
isc_netaddr_fromsockaddr(&netdst, dstaddr);
env = ns_interfacemgr_getaclenv(named_g_server->interfacemgr);
for (view = ISC_LIST_HEAD(named_g_server->viewlist); view != NULL;
view = ISC_LIST_NEXT(view, link))
@ -1315,7 +1319,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_setoption(zone, DNS_ZONEOPT_NOTIFYTOSOA,
cfg_obj_asboolean(obj));
dns_zone_setisself(zone, isself, named_g_server->interfacemgr);
dns_zone_setisself(zone, isself, NULL);
CHECK(configure_zone_acl(
zconfig, vconfig, config, allow_transfer, ac, zone,