Commit be6cc53e authored by Ondřej Surý's avatar Ondřej Surý
Browse files

Don't continue opening a new rndc connection if we are shutting down

Due to lack of synchronization, whenever named was being requested to
stop using rndc, controlconf.c module could be trying to access an already
released pointer through named_g_server->interfacemgr in a separate
thread.

The race could only be triggered if named was being shutdown and more
rndc connections were ocurring at the same time.

This fix correctly checks if the server is shutting down before opening
a new rndc connection.
parent 402e1654
......@@ -226,6 +226,7 @@ shutdown_listener(controllistener_t *listener) {
if (listener->listening) {
isc_socket_cancel(listener->sock, listener->task,
ISC_SOCKCANCEL_ACCEPT);
return;
}
maybe_free_listener(listener);
......@@ -636,6 +637,8 @@ control_newconn(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
REQUIRE(listener->listening);
listener->listening = false;
if (nevent->result != ISC_R_SUCCESS) {
......@@ -647,6 +650,14 @@ control_newconn(isc_task_t *task, isc_event_t *event) {
}
sock = nevent->newsocket;
/* Is the server shutting down? */
if (listener->controls->shuttingdown) {
isc_socket_detach(&sock);
shutdown_listener(listener);
goto cleanup;
}
isc_socket_setname(sock, "control", NULL);
(void)isc_socket_getpeername(sock, &peeraddr);
if (listener->type == isc_sockettype_tcp &&
......@@ -1121,36 +1132,33 @@ add_listener(named_controls_t *cp, controllistener_t **listenerp,
listener = isc_mem_get(mctx, sizeof(*listener));
if (result == ISC_R_SUCCESS) {
listener->mctx = NULL;
isc_mem_attach(mctx, &listener->mctx);
listener->controls = cp;
listener->task = cp->server->task;
listener->address = *addr;
listener->sock = NULL;
listener->listening = false;
listener->exiting = false;
listener->acl = NULL;
listener->type = type;
listener->perm = 0;
listener->owner = 0;
listener->group = 0;
listener->readonly = false;
ISC_LINK_INIT(listener, link);
ISC_LIST_INIT(listener->keys);
ISC_LIST_INIT(listener->connections);
listener->mctx = NULL;
isc_mem_attach(mctx, &listener->mctx);
listener->controls = cp;
listener->task = cp->server->task;
listener->address = *addr;
listener->sock = NULL;
listener->listening = false;
listener->exiting = false;
listener->acl = NULL;
listener->type = type;
listener->perm = 0;
listener->owner = 0;
listener->group = 0;
listener->readonly = false;
ISC_LINK_INIT(listener, link);
ISC_LIST_INIT(listener->keys);
ISC_LIST_INIT(listener->connections);
/*
* Make the acl.
*/
if (control != NULL && type == isc_sockettype_tcp) {
allow = cfg_tuple_get(control, "allow");
result = cfg_acl_fromconfig(allow, config, named_g_lctx,
aclconfctx, mctx, 0,
&new_acl);
} else {
result = dns_acl_any(mctx, &new_acl);
}
/*
* Make the acl.
*/
if (control != NULL && type == isc_sockettype_tcp) {
allow = cfg_tuple_get(control, "allow");
result = cfg_acl_fromconfig(allow, config, named_g_lctx,
aclconfctx, mctx, 0, &new_acl);
} else {
result = dns_acl_any(mctx, &new_acl);
}
if ((result == ISC_R_SUCCESS) && (control != NULL)) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment