2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-23 18:49:54 +00:00
bind/bin/named/controlconf.c

1496 lines
40 KiB
C
Raw Normal View History

/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*! \file */
#include <inttypes.h>
#include <stdbool.h>
#include <isc/app.h>
2001-03-27 00:45:13 +00:00
#include <isc/base64.h>
#include <isc/buffer.h>
#include <isc/event.h>
#include <isc/file.h>
2001-03-27 00:45:13 +00:00
#include <isc/mem.h>
Lock access to control->symtab to prevent data race WARNING: ThreadSanitizer: data race Read of size 8 at 0x000000000001 by thread T1: #0 isccc_symtab_foreach lib/isccc/symtab.c:277:14 #1 isccc_cc_cleansymtab lib/isccc/cc.c:954:2 #2 control_recvmessage bin/named/controlconf.c:477:2 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Previous write of size 8 at 0x000000000001 by thread T2: #0 isccc_symtab_define lib/isccc/symtab.c:242:2 #1 isccc_cc_checkdup lib/isccc/cc.c:1026:11 #2 control_recvmessage bin/named/controlconf.c:478:11 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Location is heap block of size 190352 at 0x000000000011 allocated by main thread: #0 malloc <null> #1 isccc_symtab_create lib/isccc/symtab.c:76:18 #2 isccc_cc_createsymtab lib/isccc/cc.c:948:10 #3 named_controls_create bin/named/controlconf.c:1483:11 #4 named_server_create bin/named/server.c:10057:2 #5 setup bin/named/main.c:1256:2 #6 main bin/named/main.c:1523:2 Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 SUMMARY: ThreadSanitizer: data race lib/isccc/symtab.c:277:14 in isccc_symtab_foreach
2020-09-08 12:11:06 +10:00
#include <isc/mutex.h>
#include <isc/net.h>
#include <isc/netaddr.h>
#include <isc/netmgr.h>
#include <isc/nonce.h>
#include <isc/random.h>
2001-03-27 00:45:13 +00:00
#include <isc/result.h>
#include <isc/stdtime.h>
#include <isc/string.h>
#include <isc/task.h>
2001-03-27 00:45:13 +00:00
#include <isc/util.h>
#include <dns/result.h>
2001-03-27 00:45:13 +00:00
#include <isccc/alist.h>
#include <isccc/cc.h>
#include <isccc/ccmsg.h>
#include <isccc/events.h>
#include <isccc/result.h>
#include <isccc/sexpr.h>
#include <isccc/symtab.h>
2001-03-27 00:45:13 +00:00
#include <isccc/util.h>
#include <isccfg/namedconf.h>
#include <bind9/check.h>
2001-08-03 18:12:08 +00:00
#include <named/config.h>
2001-03-27 00:45:13 +00:00
#include <named/control.h>
#include <named/log.h>
#include <named/server.h>
typedef struct controlkey controlkey_t;
typedef ISC_LIST(controlkey_t) controlkeylist_t;
typedef struct controlconnection controlconnection_t;
typedef ISC_LIST(controlconnection_t) controlconnectionlist_t;
typedef struct controllistener controllistener_t;
typedef ISC_LIST(controllistener_t) controllistenerlist_t;
struct controlkey {
2020-02-13 14:44:37 -08:00
char *keyname;
uint32_t algorithm;
isc_region_t secret;
ISC_LINK(controlkey_t) link;
2001-03-27 00:45:13 +00:00
};
struct controlconnection {
isc_nmhandle_t *readhandle;
isc_nmhandle_t *sendhandle;
isc_nmhandle_t *cmdhandle;
2020-02-13 14:44:37 -08:00
isccc_ccmsg_t ccmsg;
bool reading;
2020-02-13 14:44:37 -08:00
bool sending;
controllistener_t *listener;
isccc_sexpr_t *ctrl;
isc_buffer_t *buffer;
isc_buffer_t *text;
isccc_sexpr_t *request;
isccc_sexpr_t *response;
uint32_t alg;
isccc_region_t secret;
2020-02-13 14:44:37 -08:00
uint32_t nonce;
isc_stdtime_t now;
isc_result_t result;
ISC_LINK(controlconnection_t) link;
2001-03-27 00:45:13 +00:00
};
struct controllistener {
2020-02-13 14:44:37 -08:00
named_controls_t *controls;
isc_mem_t *mctx;
isc_sockaddr_t address;
isc_nmsocket_t *sock;
2020-02-13 14:44:37 -08:00
dns_acl_t *acl;
bool exiting;
isc_refcount_t refs;
2020-02-13 14:44:37 -08:00
controlkeylist_t keys;
Lock access to listener->connections as it is accessed from multiple threads with libuv. WARNING: ThreadSanitizer: data race Write of size 8 at 0x000000000001 by thread T1: #0 conn_reset bin/named/controlconf.c:574 #1 isc_nmhandle_detach netmgr/netmgr.c:1257 #2 isc__nm_uvreq_put netmgr/netmgr.c:1389 #3 tcp_send_cb netmgr/tcp.c:1030 #4 <null> <null> #5 <null> <null> Previous read of size 8 at 0x000000000001 by thread T2: #0 conn_reset bin/named/controlconf.c:574 #1 isc_nmhandle_detach netmgr/netmgr.c:1257 #2 control_recvmessage bin/named/controlconf.c:556 #3 recv_data lib/isccc/ccmsg.c:110 #4 isc__nm_tcp_shutdown netmgr/tcp.c:1161 #5 shutdown_walk_cb netmgr/netmgr.c:1511 #6 uv_walk <null> #7 process_queue netmgr/netmgr.c:656 #8 process_normal_queue netmgr/netmgr.c:582 #9 process_queues netmgr/netmgr.c:590 #10 async_cb netmgr/netmgr.c:548 #11 <null> <null> #12 <null> <null> Location is heap block of size 265 at 0x000000000017 allocated by thread T3: #0 malloc <null> #1 default_memalloc lib/isc/mem.c:713 #2 mem_get lib/isc/mem.c:622 #3 isc___mem_get lib/isc/mem.c:1044 #4 isc__mem_get lib/isc/mem.c:2432 #5 add_listener bin/named/controlconf.c:1127 #6 named_controls_configure bin/named/controlconf.c:1324 #7 load_configuration bin/named/server.c:9181 #8 run_server bin/named/server.c:9819 #9 dispatch lib/isc/task.c:1152 #10 run lib/isc/task.c:1344 #11 <null> <null> Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_nm_start netmgr/netmgr.c:232 #3 create_managers bin/named/main.c:909 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_nm_start netmgr/netmgr.c:232 #3 create_managers bin/named/main.c:909 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T3 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_taskmgr_create lib/isc/task.c:1434 #3 create_managers bin/named/main.c:915 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 SUMMARY: ThreadSanitizer: data race bin/named/controlconf.c:574 in conn_reset
2020-10-01 15:11:32 +10:00
isc_mutex_t connections_lock;
controlconnectionlist_t connections;
isc_socktype_t type;
2020-02-13 14:44:37 -08:00
uint32_t perm;
uint32_t owner;
uint32_t group;
bool readonly;
ISC_LINK(controllistener_t) link;
2001-03-27 00:45:13 +00:00
};
struct named_controls {
2020-02-13 14:44:37 -08:00
named_server_t *server;
controllistenerlist_t listeners;
atomic_bool shuttingdown;
Lock access to control->symtab to prevent data race WARNING: ThreadSanitizer: data race Read of size 8 at 0x000000000001 by thread T1: #0 isccc_symtab_foreach lib/isccc/symtab.c:277:14 #1 isccc_cc_cleansymtab lib/isccc/cc.c:954:2 #2 control_recvmessage bin/named/controlconf.c:477:2 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Previous write of size 8 at 0x000000000001 by thread T2: #0 isccc_symtab_define lib/isccc/symtab.c:242:2 #1 isccc_cc_checkdup lib/isccc/cc.c:1026:11 #2 control_recvmessage bin/named/controlconf.c:478:11 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Location is heap block of size 190352 at 0x000000000011 allocated by main thread: #0 malloc <null> #1 isccc_symtab_create lib/isccc/symtab.c:76:18 #2 isccc_cc_createsymtab lib/isccc/cc.c:948:10 #3 named_controls_create bin/named/controlconf.c:1483:11 #4 named_server_create bin/named/server.c:10057:2 #5 setup bin/named/main.c:1256:2 #6 main bin/named/main.c:1523:2 Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 SUMMARY: ThreadSanitizer: data race lib/isccc/symtab.c:277:14 in isccc_symtab_foreach
2020-09-08 12:11:06 +10:00
isc_mutex_t symtab_lock;
2020-02-13 14:44:37 -08:00
isccc_symtab_t *symtab;
};
2001-03-27 00:45:13 +00:00
static isc_result_t
control_newconn(isc_nmhandle_t *handle, isc_result_t result, void *arg);
2020-02-14 08:14:03 +01:00
static void
control_recvmessage(isc_nmhandle_t *handle, isc_result_t result, void *arg);
2001-03-27 00:45:13 +00:00
#define CLOCKSKEW 300
2001-03-27 00:45:13 +00:00
static void
2020-02-13 14:44:37 -08:00
free_controlkey(controlkey_t *key, isc_mem_t *mctx) {
if (key->keyname != NULL) {
2001-03-27 00:45:13 +00:00
isc_mem_free(mctx, key->keyname);
}
if (key->secret.base != NULL) {
2001-03-27 00:45:13 +00:00
isc_mem_put(mctx, key->secret.base, key->secret.length);
}
2001-03-27 00:45:13 +00:00
isc_mem_put(mctx, key, sizeof(*key));
}
static void
2020-02-13 14:44:37 -08:00
free_controlkeylist(controlkeylist_t *keylist, isc_mem_t *mctx) {
2001-03-27 00:45:13 +00:00
while (!ISC_LIST_EMPTY(*keylist)) {
controlkey_t *key = ISC_LIST_HEAD(*keylist);
ISC_LIST_UNLINK(*keylist, key, link);
free_controlkey(key, mctx);
}
}
static void
2020-02-13 14:44:37 -08:00
free_listener(controllistener_t *listener) {
2001-03-27 00:45:13 +00:00
INSIST(listener->exiting);
INSIST(ISC_LIST_EMPTY(listener->connections));
isc_refcount_destroy(&listener->refs);
if (listener->sock != NULL) {
isc_nmsocket_close(&listener->sock);
}
2001-03-27 00:45:13 +00:00
free_controlkeylist(&listener->keys, listener->mctx);
if (listener->acl != NULL) {
2001-03-27 00:45:13 +00:00
dns_acl_detach(&listener->acl);
}
Lock access to listener->connections as it is accessed from multiple threads with libuv. WARNING: ThreadSanitizer: data race Write of size 8 at 0x000000000001 by thread T1: #0 conn_reset bin/named/controlconf.c:574 #1 isc_nmhandle_detach netmgr/netmgr.c:1257 #2 isc__nm_uvreq_put netmgr/netmgr.c:1389 #3 tcp_send_cb netmgr/tcp.c:1030 #4 <null> <null> #5 <null> <null> Previous read of size 8 at 0x000000000001 by thread T2: #0 conn_reset bin/named/controlconf.c:574 #1 isc_nmhandle_detach netmgr/netmgr.c:1257 #2 control_recvmessage bin/named/controlconf.c:556 #3 recv_data lib/isccc/ccmsg.c:110 #4 isc__nm_tcp_shutdown netmgr/tcp.c:1161 #5 shutdown_walk_cb netmgr/netmgr.c:1511 #6 uv_walk <null> #7 process_queue netmgr/netmgr.c:656 #8 process_normal_queue netmgr/netmgr.c:582 #9 process_queues netmgr/netmgr.c:590 #10 async_cb netmgr/netmgr.c:548 #11 <null> <null> #12 <null> <null> Location is heap block of size 265 at 0x000000000017 allocated by thread T3: #0 malloc <null> #1 default_memalloc lib/isc/mem.c:713 #2 mem_get lib/isc/mem.c:622 #3 isc___mem_get lib/isc/mem.c:1044 #4 isc__mem_get lib/isc/mem.c:2432 #5 add_listener bin/named/controlconf.c:1127 #6 named_controls_configure bin/named/controlconf.c:1324 #7 load_configuration bin/named/server.c:9181 #8 run_server bin/named/server.c:9819 #9 dispatch lib/isc/task.c:1152 #10 run lib/isc/task.c:1344 #11 <null> <null> Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_nm_start netmgr/netmgr.c:232 #3 create_managers bin/named/main.c:909 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_nm_start netmgr/netmgr.c:232 #3 create_managers bin/named/main.c:909 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T3 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_taskmgr_create lib/isc/task.c:1434 #3 create_managers bin/named/main.c:915 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 SUMMARY: ThreadSanitizer: data race bin/named/controlconf.c:574 in conn_reset
2020-10-01 15:11:32 +10:00
isc_mutex_destroy(&listener->connections_lock);
2001-03-27 00:45:13 +00:00
isc_mem_putanddetach(&listener->mctx, listener, sizeof(*listener));
2001-03-27 00:45:13 +00:00
}
static void
2020-02-13 14:44:37 -08:00
maybe_free_listener(controllistener_t *listener) {
if (isc_refcount_decrement(&listener->refs) == 1) {
2001-03-27 00:45:13 +00:00
free_listener(listener);
}
2001-03-27 00:45:13 +00:00
}
static void
2020-02-13 14:44:37 -08:00
shutdown_listener(controllistener_t *listener) {
if (!listener->exiting) {
char socktext[ISC_SOCKADDR_FORMATSIZE];
ISC_LIST_UNLINK(listener->controls->listeners, listener, link);
isc_sockaddr_format(&listener->address, socktext,
sizeof(socktext));
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL, ISC_LOG_NOTICE,
"stopping command channel on %s", socktext);
#if 0
/* XXX: no unix domain socket support */
if (listener->type == isc_socktype_unix) {
isc_socket_cleanunix(&listener->address, true);
}
#endif
listener->exiting = true;
}
2001-03-27 00:45:13 +00:00
isc_nm_stoplistening(listener->sock);
maybe_free_listener(listener);
2001-03-27 00:45:13 +00:00
}
static bool
address_ok(isc_sockaddr_t *sockaddr, controllistener_t *listener) {
dns_aclenv_t *env =
ns_interfacemgr_getaclenv(named_g_server->interfacemgr);
2001-03-27 00:45:13 +00:00
isc_netaddr_t netaddr;
2020-02-13 14:44:37 -08:00
isc_result_t result;
int match;
2001-03-27 00:45:13 +00:00
/* ACL doesn't apply to unix domain sockets */
if (listener->type != isc_socktype_tcp) {
return (true);
}
2001-03-27 00:45:13 +00:00
isc_netaddr_fromsockaddr(&netaddr, sockaddr);
2001-03-27 00:45:13 +00:00
result = dns_acl_match(&netaddr, NULL, listener->acl, env, &match,
NULL);
return (result == ISC_R_SUCCESS && match > 0);
2001-03-27 00:45:13 +00:00
}
static void
control_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
controlconnection_t *conn = (controlconnection_t *)arg;
2020-02-13 14:44:37 -08:00
controllistener_t *listener = conn->listener;
isc_sockaddr_t peeraddr = isc_nmhandle_peeraddr(handle);
2001-03-27 00:45:13 +00:00
REQUIRE(conn->sending);
conn->sending = false;
2001-03-27 00:45:13 +00:00
if (conn->result == ISC_R_SHUTTINGDOWN) {
isc_app_shutdown();
goto cleanup_sendhandle;
}
if (atomic_load_acquire(&listener->controls->shuttingdown) ||
result == ISC_R_CANCELED)
{
goto cleanup_sendhandle;
} else if (result != ISC_R_SUCCESS) {
2020-02-13 14:44:37 -08:00
char socktext[ISC_SOCKADDR_FORMATSIZE];
2001-03-27 00:45:13 +00:00
isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL, ISC_LOG_WARNING,
2001-03-27 00:45:13 +00:00
"error sending command response to %s: %s",
socktext, isc_result_totext(result));
goto cleanup_sendhandle;
2001-03-27 00:45:13 +00:00
}
isc_nmhandle_attach(handle, &conn->readhandle);
conn->reading = true;
isc_nmhandle_detach(&conn->sendhandle);
isccc_ccmsg_readmessage(&conn->ccmsg, control_recvmessage, conn);
return;
cleanup_sendhandle:
isc_nmhandle_detach(&conn->sendhandle);
2001-03-27 00:45:13 +00:00
}
static inline void
2020-02-13 14:44:37 -08:00
log_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) {
char socktext[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_t peeraddr = isc_nmhandle_peeraddr(ccmsg->handle);
2001-03-27 00:45:13 +00:00
isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL, ISC_LOG_ERROR,
"invalid command from %s: %s", socktext,
isc_result_totext(result));
2001-03-27 00:45:13 +00:00
}
static void
conn_cleanup(controlconnection_t *conn) {
controllistener_t *listener = conn->listener;
if (conn->response != NULL) {
isccc_sexpr_free(&conn->response);
}
if (conn->request != NULL) {
isccc_sexpr_free(&conn->request);
}
if (conn->secret.rstart != NULL) {
isc_mem_put(listener->mctx, conn->secret.rstart,
REGION_SIZE(conn->secret));
}
if (conn->text != NULL) {
isc_buffer_free(&conn->text);
}
}
2001-03-27 00:45:13 +00:00
static void
control_respond(isc_nmhandle_t *handle, controlconnection_t *conn) {
controllistener_t *listener = conn->listener;
isccc_sexpr_t *data = NULL;
2020-02-13 14:44:37 -08:00
isc_buffer_t b;
isc_region_t r;
isc_result_t result;
result = isccc_cc_createresponse(conn->request, conn->now,
conn->now + 60, &conn->response);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
if (conn->result == ISC_R_SHUTTINGDOWN) {
result = ISC_R_SUCCESS;
} else {
result = conn->result;
}
data = isccc_alist_lookup(conn->response, "_data");
if (data != NULL) {
if (isccc_cc_defineuint32(data, "result", result) == NULL) {
goto cleanup;
}
}
if (result != ISC_R_SUCCESS) {
if (data != NULL) {
const char *estr = isc_result_totext(result);
if (isccc_cc_definestring(data, "err", estr) == NULL) {
goto cleanup;
}
}
}
if (isc_buffer_usedlength(conn->text) > 0) {
if (data != NULL) {
char *str = (char *)isc_buffer_base(conn->text);
if (isccc_cc_definestring(data, "text", str) == NULL) {
goto cleanup;
}
}
}
conn->ctrl = isccc_alist_lookup(conn->response, "_ctrl");
if (conn->ctrl == NULL ||
isccc_cc_defineuint32(conn->ctrl, "_nonce", conn->nonce) == NULL)
{
goto cleanup;
}
if (conn->buffer == NULL) {
isc_buffer_allocate(listener->mctx, &conn->buffer, 2 * 2048);
}
isc_buffer_clear(conn->buffer);
/* Skip the length field (4 bytes) */
isc_buffer_add(conn->buffer, 4);
result = isccc_cc_towire(conn->response, &conn->buffer, conn->alg,
&conn->secret);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
isc_buffer_init(&b, conn->buffer->base, 4);
isc_buffer_putuint32(&b, conn->buffer->used - 4);
r.base = conn->buffer->base;
r.length = conn->buffer->used;
isc_nmhandle_attach(handle, &conn->sendhandle);
conn->sending = true;
conn_cleanup(conn);
isc_nmhandle_detach(&conn->cmdhandle);
isc_nm_send(conn->sendhandle, &r, control_senddone, conn);
return;
cleanup:
conn_cleanup(conn);
isc_nmhandle_detach(&conn->cmdhandle);
}
static void
control_command(isc_task_t *task, isc_event_t *event) {
controlconnection_t *conn = event->ev_arg;
controllistener_t *listener = conn->listener;
UNUSED(task);
if (atomic_load_acquire(&listener->controls->shuttingdown)) {
conn_cleanup(conn);
2020-09-17 15:18:27 +10:00
isc_nmhandle_detach(&conn->cmdhandle);
goto done;
}
conn->result = named_control_docommand(conn->request,
listener->readonly, &conn->text);
control_respond(conn->cmdhandle, conn);
done:
isc_event_free(&event);
}
static void
control_recvmessage(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
controlconnection_t *conn = (controlconnection_t *)arg;
controllistener_t *listener = conn->listener;
controlkey_t *key = NULL;
isc_event_t *event = NULL;
2020-02-13 14:44:37 -08:00
isccc_time_t sent;
isccc_time_t exp;
uint32_t nonce;
2001-03-27 00:45:13 +00:00
conn->reading = false;
2001-03-27 00:45:13 +00:00
2008-01-18 23:46:58 +00:00
/* Is the server shutting down? */
if (atomic_load_acquire(&listener->controls->shuttingdown)) {
goto cleanup_readhandle;
}
if (result != ISC_R_SUCCESS) {
if (result == ISC_R_CANCELED) {
atomic_store_release(&listener->controls->shuttingdown,
true);
} else if (result != ISC_R_EOF) {
log_invalid(&conn->ccmsg, result);
}
goto cleanup_readhandle;
2001-03-27 00:45:13 +00:00
}
for (key = ISC_LIST_HEAD(listener->keys); key != NULL;
2020-02-13 14:44:37 -08:00
key = ISC_LIST_NEXT(key, link))
{
isccc_region_t ccregion;
ccregion.rstart = isc_buffer_base(conn->ccmsg.buffer);
ccregion.rend = isc_buffer_used(conn->ccmsg.buffer);
conn->secret.rstart = isc_mem_get(listener->mctx,
key->secret.length);
memmove(conn->secret.rstart, key->secret.base,
key->secret.length);
conn->secret.rend = conn->secret.rstart + key->secret.length;
conn->alg = key->algorithm;
result = isccc_cc_fromwire(&ccregion, &conn->request, conn->alg,
&conn->secret);
if (result == ISC_R_SUCCESS) {
break;
}
isc_mem_put(listener->mctx, conn->secret.rstart,
REGION_SIZE(conn->secret));
if (result != ISCCC_R_BADAUTH) {
log_invalid(&conn->ccmsg, result);
goto cleanup;
}
}
if (key == NULL) {
log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH);
2001-03-27 00:45:13 +00:00
goto cleanup;
}
/* We shouldn't be getting a reply. */
if (isccc_cc_isreply(conn->request)) {
2001-03-27 00:45:13 +00:00
log_invalid(&conn->ccmsg, ISC_R_FAILURE);
goto cleanup;
2001-03-27 00:45:13 +00:00
}
isc_stdtime_get(&conn->now);
/*
* Limit exposure to replay attacks.
*/
conn->ctrl = isccc_alist_lookup(conn->request, "_ctrl");
if (!isccc_alist_alistp(conn->ctrl)) {
log_invalid(&conn->ccmsg, ISC_R_FAILURE);
goto cleanup;
}
if (isccc_cc_lookupuint32(conn->ctrl, "_tim", &sent) == ISC_R_SUCCESS) {
if ((sent + CLOCKSKEW) < conn->now ||
(sent - CLOCKSKEW) > conn->now) {
log_invalid(&conn->ccmsg, ISCCC_R_CLOCKSKEW);
goto cleanup;
}
} else {
log_invalid(&conn->ccmsg, ISC_R_FAILURE);
goto cleanup;
}
/*
* Expire messages that are too old.
*/
if (isccc_cc_lookupuint32(conn->ctrl, "_exp", &exp) == ISC_R_SUCCESS &&
conn->now > exp)
{
log_invalid(&conn->ccmsg, ISCCC_R_EXPIRED);
goto cleanup;
}
/*
* Duplicate suppression (required for UDP).
*/
Lock access to control->symtab to prevent data race WARNING: ThreadSanitizer: data race Read of size 8 at 0x000000000001 by thread T1: #0 isccc_symtab_foreach lib/isccc/symtab.c:277:14 #1 isccc_cc_cleansymtab lib/isccc/cc.c:954:2 #2 control_recvmessage bin/named/controlconf.c:477:2 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Previous write of size 8 at 0x000000000001 by thread T2: #0 isccc_symtab_define lib/isccc/symtab.c:242:2 #1 isccc_cc_checkdup lib/isccc/cc.c:1026:11 #2 control_recvmessage bin/named/controlconf.c:478:11 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Location is heap block of size 190352 at 0x000000000011 allocated by main thread: #0 malloc <null> #1 isccc_symtab_create lib/isccc/symtab.c:76:18 #2 isccc_cc_createsymtab lib/isccc/cc.c:948:10 #3 named_controls_create bin/named/controlconf.c:1483:11 #4 named_server_create bin/named/server.c:10057:2 #5 setup bin/named/main.c:1256:2 #6 main bin/named/main.c:1523:2 Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 SUMMARY: ThreadSanitizer: data race lib/isccc/symtab.c:277:14 in isccc_symtab_foreach
2020-09-08 12:11:06 +10:00
LOCK(&listener->controls->symtab_lock);
isccc_cc_cleansymtab(listener->controls->symtab, conn->now);
result = isccc_cc_checkdup(listener->controls->symtab, conn->request,
conn->now);
Lock access to control->symtab to prevent data race WARNING: ThreadSanitizer: data race Read of size 8 at 0x000000000001 by thread T1: #0 isccc_symtab_foreach lib/isccc/symtab.c:277:14 #1 isccc_cc_cleansymtab lib/isccc/cc.c:954:2 #2 control_recvmessage bin/named/controlconf.c:477:2 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Previous write of size 8 at 0x000000000001 by thread T2: #0 isccc_symtab_define lib/isccc/symtab.c:242:2 #1 isccc_cc_checkdup lib/isccc/cc.c:1026:11 #2 control_recvmessage bin/named/controlconf.c:478:11 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Location is heap block of size 190352 at 0x000000000011 allocated by main thread: #0 malloc <null> #1 isccc_symtab_create lib/isccc/symtab.c:76:18 #2 isccc_cc_createsymtab lib/isccc/cc.c:948:10 #3 named_controls_create bin/named/controlconf.c:1483:11 #4 named_server_create bin/named/server.c:10057:2 #5 setup bin/named/main.c:1256:2 #6 main bin/named/main.c:1523:2 Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 SUMMARY: ThreadSanitizer: data race lib/isccc/symtab.c:277:14 in isccc_symtab_foreach
2020-09-08 12:11:06 +10:00
UNLOCK(&listener->controls->symtab_lock);
if (result != ISC_R_SUCCESS) {
if (result == ISC_R_EXISTS) {
2008-01-18 23:46:58 +00:00
result = ISCCC_R_DUPLICATE;
}
log_invalid(&conn->ccmsg, result);
goto cleanup;
}
if (conn->nonce != 0 &&
(isccc_cc_lookupuint32(conn->ctrl, "_nonce", &nonce) !=
ISC_R_SUCCESS ||
2020-02-13 14:44:37 -08:00
conn->nonce != nonce))
{
log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH);
goto cleanup;
}
isc_buffer_allocate(listener->mctx, &conn->text, 2 * 2048);
isc_nmhandle_attach(handle, &conn->cmdhandle);
isc_nmhandle_detach(&conn->readhandle);
if (conn->nonce == 0) {
/*
* Establish nonce.
*/
while (conn->nonce == 0) {
isc_nonce_buf(&conn->nonce, sizeof(conn->nonce));
}
conn->result = ISC_R_SUCCESS;
control_respond(handle, conn);
return;
2001-03-27 00:45:13 +00:00
}
/*
* Trigger the command.
*/
event = isc_event_allocate(listener->mctx, conn, NAMED_EVENT_COMMAND,
control_command, conn, sizeof(isc_event_t));
isc_task_send(named_g_server->task, &event);
return;
cleanup:
conn_cleanup(conn);
cleanup_readhandle:
/*
* readhandle could be NULL if we're shutting down,
* but if not we need to detach it.
*/
if (conn->readhandle != NULL) {
isc_nmhandle_detach(&conn->readhandle);
}
2001-03-27 00:45:13 +00:00
}
static void
conn_reset(void *arg) {
controlconnection_t *conn = (controlconnection_t *)arg;
controllistener_t *listener = conn->listener;
2001-03-27 00:45:13 +00:00
if (conn->buffer != NULL) {
isc_buffer_free(&conn->buffer);
}
2001-03-27 00:45:13 +00:00
if (conn->reading) {
isccc_ccmsg_cancelread(&conn->ccmsg);
return;
}
2001-03-27 00:45:13 +00:00
Lock access to listener->connections as it is accessed from multiple threads with libuv. WARNING: ThreadSanitizer: data race Write of size 8 at 0x000000000001 by thread T1: #0 conn_reset bin/named/controlconf.c:574 #1 isc_nmhandle_detach netmgr/netmgr.c:1257 #2 isc__nm_uvreq_put netmgr/netmgr.c:1389 #3 tcp_send_cb netmgr/tcp.c:1030 #4 <null> <null> #5 <null> <null> Previous read of size 8 at 0x000000000001 by thread T2: #0 conn_reset bin/named/controlconf.c:574 #1 isc_nmhandle_detach netmgr/netmgr.c:1257 #2 control_recvmessage bin/named/controlconf.c:556 #3 recv_data lib/isccc/ccmsg.c:110 #4 isc__nm_tcp_shutdown netmgr/tcp.c:1161 #5 shutdown_walk_cb netmgr/netmgr.c:1511 #6 uv_walk <null> #7 process_queue netmgr/netmgr.c:656 #8 process_normal_queue netmgr/netmgr.c:582 #9 process_queues netmgr/netmgr.c:590 #10 async_cb netmgr/netmgr.c:548 #11 <null> <null> #12 <null> <null> Location is heap block of size 265 at 0x000000000017 allocated by thread T3: #0 malloc <null> #1 default_memalloc lib/isc/mem.c:713 #2 mem_get lib/isc/mem.c:622 #3 isc___mem_get lib/isc/mem.c:1044 #4 isc__mem_get lib/isc/mem.c:2432 #5 add_listener bin/named/controlconf.c:1127 #6 named_controls_configure bin/named/controlconf.c:1324 #7 load_configuration bin/named/server.c:9181 #8 run_server bin/named/server.c:9819 #9 dispatch lib/isc/task.c:1152 #10 run lib/isc/task.c:1344 #11 <null> <null> Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_nm_start netmgr/netmgr.c:232 #3 create_managers bin/named/main.c:909 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_nm_start netmgr/netmgr.c:232 #3 create_managers bin/named/main.c:909 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T3 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_taskmgr_create lib/isc/task.c:1434 #3 create_managers bin/named/main.c:915 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 SUMMARY: ThreadSanitizer: data race bin/named/controlconf.c:574 in conn_reset
2020-10-01 15:11:32 +10:00
LOCK(&listener->connections_lock);
ISC_LIST_UNLINK(listener->connections, conn, link);
Lock access to listener->connections as it is accessed from multiple threads with libuv. WARNING: ThreadSanitizer: data race Write of size 8 at 0x000000000001 by thread T1: #0 conn_reset bin/named/controlconf.c:574 #1 isc_nmhandle_detach netmgr/netmgr.c:1257 #2 isc__nm_uvreq_put netmgr/netmgr.c:1389 #3 tcp_send_cb netmgr/tcp.c:1030 #4 <null> <null> #5 <null> <null> Previous read of size 8 at 0x000000000001 by thread T2: #0 conn_reset bin/named/controlconf.c:574 #1 isc_nmhandle_detach netmgr/netmgr.c:1257 #2 control_recvmessage bin/named/controlconf.c:556 #3 recv_data lib/isccc/ccmsg.c:110 #4 isc__nm_tcp_shutdown netmgr/tcp.c:1161 #5 shutdown_walk_cb netmgr/netmgr.c:1511 #6 uv_walk <null> #7 process_queue netmgr/netmgr.c:656 #8 process_normal_queue netmgr/netmgr.c:582 #9 process_queues netmgr/netmgr.c:590 #10 async_cb netmgr/netmgr.c:548 #11 <null> <null> #12 <null> <null> Location is heap block of size 265 at 0x000000000017 allocated by thread T3: #0 malloc <null> #1 default_memalloc lib/isc/mem.c:713 #2 mem_get lib/isc/mem.c:622 #3 isc___mem_get lib/isc/mem.c:1044 #4 isc__mem_get lib/isc/mem.c:2432 #5 add_listener bin/named/controlconf.c:1127 #6 named_controls_configure bin/named/controlconf.c:1324 #7 load_configuration bin/named/server.c:9181 #8 run_server bin/named/server.c:9819 #9 dispatch lib/isc/task.c:1152 #10 run lib/isc/task.c:1344 #11 <null> <null> Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_nm_start netmgr/netmgr.c:232 #3 create_managers bin/named/main.c:909 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_nm_start netmgr/netmgr.c:232 #3 create_managers bin/named/main.c:909 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T3 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_taskmgr_create lib/isc/task.c:1434 #3 create_managers bin/named/main.c:915 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 SUMMARY: ThreadSanitizer: data race bin/named/controlconf.c:574 in conn_reset
2020-10-01 15:11:32 +10:00
UNLOCK(&listener->connections_lock);
#ifdef ENABLE_AFL
if (named_g_fuzz_type == isc_fuzz_rndc) {
named_fuzz_notify();
}
#endif /* ifdef ENABLE_AFL */
isccc_ccmsg_invalidate(&conn->ccmsg);
}
static void
conn_put(void *arg) {
controlconnection_t *conn = (controlconnection_t *)arg;
controllistener_t *listener = conn->listener;
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL, ISC_LOG_DEBUG(3),
"freeing control connection");
maybe_free_listener(listener);
2001-03-27 00:45:13 +00:00
}
static void
newconnection(controllistener_t *listener, isc_nmhandle_t *handle) {
controlconnection_t *conn = NULL;
2001-03-27 00:45:13 +00:00
conn = isc_nmhandle_getdata(handle);
if (conn == NULL) {
conn = isc_nmhandle_getextra(handle);
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL, ISC_LOG_DEBUG(3),
"allocate new control connection");
isc_nmhandle_setdata(handle, conn, conn_reset, conn_put);
isc_refcount_increment(&listener->refs);
}
2008-01-18 23:46:58 +00:00
*conn = (controlconnection_t){ .listener = listener,
.reading = false,
.alg = DST_ALG_UNKNOWN };
isccc_ccmsg_init(listener->mctx, handle, &conn->ccmsg);
/* Set a 32 KiB upper limit on incoming message. */
isccc_ccmsg_setmaxsize(&conn->ccmsg, 32768);
LOCK(&listener->connections_lock);
ISC_LIST_INITANDAPPEND(listener->connections, conn, link);
UNLOCK(&listener->connections_lock);
2001-03-27 00:45:13 +00:00
isc_nmhandle_attach(handle, &conn->readhandle);
conn->reading = true;
isccc_ccmsg_readmessage(&conn->ccmsg, control_recvmessage, conn);
2001-03-27 00:45:13 +00:00
}
static isc_result_t
control_newconn(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
controllistener_t *listener = arg;
2020-02-13 14:44:37 -08:00
isc_sockaddr_t peeraddr;
if (result != ISC_R_SUCCESS) {
if (result == ISC_R_CANCELED) {
2001-03-27 00:45:13 +00:00
shutdown_listener(listener);
}
return (result);
2001-03-27 00:45:13 +00:00
}
peeraddr = isc_nmhandle_peeraddr(handle);
if (!address_ok(&peeraddr, listener)) {
2001-03-27 00:45:13 +00:00
char socktext[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL, ISC_LOG_WARNING,
2001-03-27 00:45:13 +00:00
"rejected command channel message from %s",
socktext);
return (ISC_R_FAILURE);
2001-03-27 00:45:13 +00:00
}
newconnection(listener, handle);
return (ISC_R_SUCCESS);
2001-03-27 00:45:13 +00:00
}
static void
2020-02-13 14:44:37 -08:00
controls_shutdown(named_controls_t *controls) {
controllistener_t *listener = NULL;
controllistener_t *next = NULL;
2001-03-27 00:45:13 +00:00
for (listener = ISC_LIST_HEAD(controls->listeners); listener != NULL;
2020-02-13 14:44:37 -08:00
listener = next)
{
2001-03-27 00:45:13 +00:00
/*
* This is asynchronous. As listeners shut down, they will
* call their callbacks.
*/
next = ISC_LIST_NEXT(listener, link);
shutdown_listener(listener);
}
}
void
2020-02-13 14:44:37 -08:00
named_controls_shutdown(named_controls_t *controls) {
controls_shutdown(controls);
atomic_store_release(&controls->shuttingdown, true);
2001-03-27 00:45:13 +00:00
}
static isc_result_t
cfgkeylist_find(const cfg_obj_t *keylist, const char *keyname,
2020-02-13 14:44:37 -08:00
const cfg_obj_t **objp) {
const cfg_listelt_t *element = NULL;
const char *str = NULL;
const cfg_obj_t *obj = NULL;
2001-03-27 00:45:13 +00:00
for (element = cfg_list_first(keylist); element != NULL;
2020-02-13 14:44:37 -08:00
element = cfg_list_next(element))
{
2001-03-27 00:45:13 +00:00
obj = cfg_listelt_value(element);
str = cfg_obj_asstring(cfg_map_getname(obj));
if (strcasecmp(str, keyname) == 0) {
2001-03-27 00:45:13 +00:00
break;
}
2001-03-27 00:45:13 +00:00
}
if (element == NULL) {
2001-03-27 00:45:13 +00:00
return (ISC_R_NOTFOUND);
}
2001-03-27 00:45:13 +00:00
obj = cfg_listelt_value(element);
*objp = obj;
return (ISC_R_SUCCESS);
}
static void
controlkeylist_fromcfg(const cfg_obj_t *keylist, isc_mem_t *mctx,
2020-02-13 14:44:37 -08:00
controlkeylist_t *keyids) {
const cfg_listelt_t *element = NULL;
2020-02-13 14:44:37 -08:00
char *newstr = NULL;
const char *str = NULL;
const cfg_obj_t *obj = NULL;
controlkey_t *key = NULL;
for (element = cfg_list_first(keylist); element != NULL;
2020-02-13 14:44:37 -08:00
element = cfg_list_next(element))
{
2001-03-27 00:45:13 +00:00
obj = cfg_listelt_value(element);
str = cfg_obj_asstring(obj);
newstr = isc_mem_strdup(mctx, str);
key = isc_mem_get(mctx, sizeof(*key));
key->keyname = newstr;
key->algorithm = DST_ALG_UNKNOWN;
2001-03-27 00:45:13 +00:00
key->secret.base = NULL;
key->secret.length = 0;
ISC_LINK_INIT(key, link);
ISC_LIST_APPEND(*keyids, key, link);
newstr = NULL;
}
}
static void
register_keys(const cfg_obj_t *control, const cfg_obj_t *keylist,
2020-02-13 14:44:37 -08:00
controlkeylist_t *keyids, isc_mem_t *mctx, const char *socktext) {
controlkey_t *keyid = NULL, *next = NULL;
const cfg_obj_t *keydef = NULL;
2020-02-13 14:44:37 -08:00
char secret[1024];
isc_buffer_t b;
isc_result_t result;
2001-03-27 00:45:13 +00:00
/*
* Find the keys corresponding to the keyids used by this listener.
*/
for (keyid = ISC_LIST_HEAD(*keyids); keyid != NULL; keyid = next) {
next = ISC_LIST_NEXT(keyid, link);
result = cfgkeylist_find(keylist, keyid->keyname, &keydef);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(control, named_g_lctx, ISC_LOG_WARNING,
"couldn't find key '%s' for use with "
2001-03-27 00:45:13 +00:00
"command channel %s",
keyid->keyname, socktext);
ISC_LIST_UNLINK(*keyids, keyid, link);
free_controlkey(keyid, mctx);
} else {
const cfg_obj_t *algobj = NULL;
const cfg_obj_t *secretobj = NULL;
2020-02-13 14:44:37 -08:00
const char *algstr = NULL;
const char *secretstr = NULL;
unsigned int algtype;
2001-03-27 00:45:13 +00:00
(void)cfg_map_get(keydef, "algorithm", &algobj);
(void)cfg_map_get(keydef, "secret", &secretobj);
INSIST(algobj != NULL && secretobj != NULL);
algstr = cfg_obj_asstring(algobj);
secretstr = cfg_obj_asstring(secretobj);
result = named_config_getkeyalgorithm2(algstr, NULL,
&algtype, NULL);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(control, named_g_lctx,
2001-03-27 00:45:13 +00:00
ISC_LOG_WARNING,
"unsupported algorithm '%s' in "
"key '%s' for use with command "
"channel %s",
algstr, keyid->keyname, socktext);
ISC_LIST_UNLINK(*keyids, keyid, link);
free_controlkey(keyid, mctx);
continue;
}
keyid->algorithm = algtype;
2001-03-27 00:45:13 +00:00
isc_buffer_init(&b, secret, sizeof(secret));
result = isc_base64_decodestring(secretstr, &b);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(keydef, named_g_lctx,
ISC_LOG_WARNING,
2001-03-27 00:45:13 +00:00
"secret for key '%s' on "
"command channel %s: %s",
keyid->keyname, socktext,
isc_result_totext(result));
ISC_LIST_UNLINK(*keyids, keyid, link);
free_controlkey(keyid, mctx);
continue;
}
keyid->secret.length = isc_buffer_usedlength(&b);
2020-02-13 14:44:37 -08:00
keyid->secret.base = isc_mem_get(mctx,
keyid->secret.length);
memmove(keyid->secret.base, isc_buffer_base(&b),
keyid->secret.length);
2001-03-27 00:45:13 +00:00
}
}
}
#define CHECK(x) \
do { \
result = (x); \
if (result != ISC_R_SUCCESS) { \
goto cleanup; \
} \
2001-08-03 05:56:22 +00:00
} while (0)
2008-01-18 23:46:58 +00:00
static isc_result_t
2020-02-13 14:44:37 -08:00
get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
isc_result_t result;
cfg_parser_t *pctx = NULL;
cfg_obj_t *config = NULL;
const cfg_obj_t *key = NULL;
const cfg_obj_t *algobj = NULL;
const cfg_obj_t *secretobj = NULL;
2020-02-13 14:44:37 -08:00
const char *algstr = NULL;
const char *secretstr = NULL;
controlkey_t *keyid = NULL;
char secret[1024];
unsigned int algtype;
isc_buffer_t b;
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL, ISC_LOG_INFO,
"configuring command channel from '%s'", named_g_keyfile);
if (!isc_file_exists(named_g_keyfile)) {
return (ISC_R_FILENOTFOUND);
}
CHECK(cfg_parser_create(mctx, named_g_lctx, &pctx));
CHECK(cfg_parse_file(pctx, named_g_keyfile, &cfg_type_rndckey,
&config));
2001-08-03 05:56:22 +00:00
CHECK(cfg_map_get(config, "key", &key));
keyid = isc_mem_get(mctx, sizeof(*keyid));
2020-02-13 14:44:37 -08:00
keyid->keyname = isc_mem_strdup(mctx,
cfg_obj_asstring(cfg_map_getname(key)));
2001-08-03 05:56:22 +00:00
keyid->secret.base = NULL;
keyid->secret.length = 0;
keyid->algorithm = DST_ALG_UNKNOWN;
2001-08-03 05:56:22 +00:00
ISC_LINK_INIT(keyid, link);
if (keyid->keyname == NULL) {
2001-08-03 05:56:22 +00:00
CHECK(ISC_R_NOMEMORY);
}
2001-08-03 05:56:22 +00:00
CHECK(bind9_check_key(key, named_g_lctx));
2001-08-03 05:56:22 +00:00
(void)cfg_map_get(key, "algorithm", &algobj);
(void)cfg_map_get(key, "secret", &secretobj);
INSIST(algobj != NULL && secretobj != NULL);
algstr = cfg_obj_asstring(algobj);
secretstr = cfg_obj_asstring(secretobj);
result = named_config_getkeyalgorithm2(algstr, NULL, &algtype, NULL);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING,
2001-08-03 05:56:22 +00:00
"unsupported algorithm '%s' in "
"key '%s' for use with command "
"channel",
algstr, keyid->keyname);
goto cleanup;
}
keyid->algorithm = algtype;
2001-08-03 05:56:22 +00:00
isc_buffer_init(&b, secret, sizeof(secret));
result = isc_base64_decodestring(secretstr, &b);
2001-08-03 05:56:22 +00:00
if (result != ISC_R_SUCCESS) {
cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING,
2001-08-03 05:56:22 +00:00
"secret for key '%s' on command channel: %s",
keyid->keyname, isc_result_totext(result));
goto cleanup;
}
2001-08-03 05:56:22 +00:00
keyid->secret.length = isc_buffer_usedlength(&b);
keyid->secret.base = isc_mem_get(mctx, keyid->secret.length);
memmove(keyid->secret.base, isc_buffer_base(&b), keyid->secret.length);
2001-08-03 05:56:22 +00:00
ISC_LIST_APPEND(*keyids, keyid, link);
keyid = NULL;
result = ISC_R_SUCCESS;
cleanup:
if (keyid != NULL) {
2001-08-03 05:56:22 +00:00
free_controlkey(keyid, mctx);
}
if (config != NULL) {
2001-08-03 05:56:22 +00:00
cfg_obj_destroy(pctx, &config);
}
if (pctx != NULL) {
2001-08-03 05:56:22 +00:00
cfg_parser_destroy(&pctx);
}
return (result);
}
2008-01-18 23:46:58 +00:00
/*
* Ensures that both '*global_keylistp' and '*control_keylistp' are
* valid or both are NULL.
*/
static void
get_key_info(const cfg_obj_t *config, const cfg_obj_t *control,
const cfg_obj_t **global_keylistp,
2020-02-13 14:44:37 -08:00
const cfg_obj_t **control_keylistp) {
isc_result_t result;
const cfg_obj_t *control_keylist = NULL;
const cfg_obj_t *global_keylist = NULL;
REQUIRE(global_keylistp != NULL && *global_keylistp == NULL);
REQUIRE(control_keylistp != NULL && *control_keylistp == NULL);
control_keylist = cfg_tuple_get(control, "keys");
2001-08-03 05:56:22 +00:00
if (!cfg_obj_isvoid(control_keylist) &&
cfg_list_first(control_keylist) != NULL) {
result = cfg_map_get(config, "key", &global_keylist);
if (result == ISC_R_SUCCESS) {
*global_keylistp = global_keylist;
*control_keylistp = control_keylist;
}
}
}
2001-03-27 00:45:13 +00:00
static void
update_listener(named_controls_t *cp, controllistener_t **listenerp,
const cfg_obj_t *control, const cfg_obj_t *config,
isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx,
const char *socktext, isc_socktype_t type) {
controllistener_t *listener = NULL;
const cfg_obj_t *allow = NULL;
2020-02-13 14:44:37 -08:00
const cfg_obj_t *global_keylist = NULL;
const cfg_obj_t *control_keylist = NULL;
dns_acl_t *new_acl = NULL;
controlkeylist_t keys;
isc_result_t result = ISC_R_SUCCESS;
for (listener = ISC_LIST_HEAD(cp->listeners); listener != NULL;
2020-02-13 14:44:37 -08:00
listener = ISC_LIST_NEXT(listener, link))
{
if (isc_sockaddr_equal(addr, &listener->address)) {
2001-03-27 00:45:13 +00:00
break;
}
}
2001-03-27 00:45:13 +00:00
if (listener == NULL) {
*listenerp = NULL;
return;
}
2008-01-18 23:46:58 +00:00
2001-03-27 00:45:13 +00:00
/*
* There is already a listener for this sockaddr.
* Update the access list and key information.
*
* First try to deal with the key situation. There are a few
* possibilities:
* (a) It had an explicit keylist and still has an explicit keylist.
* (b) It had an automagic key and now has an explicit keylist.
* (c) It had an explicit keylist and now needs an automagic key.
* (d) It has an automagic key and still needs the automagic key.
*
* (c) and (d) are the annoying ones. The caller needs to know
* that it should use the automagic configuration for key information
* in place of the named.conf configuration.
*
* XXXDCL There is one other hazard that has not been dealt with,
* the problem that if a key change is being caused by a control
* channel reload, then the response will be with the new key
* and not able to be decrypted by the client.
*/
if (control != NULL) {
get_key_info(config, control, &global_keylist,
&control_keylist);
}
if (control_keylist != NULL) {
INSIST(global_keylist != NULL);
ISC_LIST_INIT(keys);
controlkeylist_fromcfg(control_keylist, listener->mctx, &keys);
free_controlkeylist(&listener->keys, listener->mctx);
listener->keys = keys;
register_keys(control, global_keylist, &listener->keys,
listener->mctx, socktext);
2001-08-03 05:56:22 +00:00
} else {
free_controlkeylist(&listener->keys, listener->mctx);
2001-08-03 05:56:22 +00:00
result = get_rndckey(listener->mctx, &listener->keys);
}
2005-11-30 03:36:45 +00:00
if (result != ISC_R_SUCCESS && global_keylist != NULL) {
/*
* This message might be a little misleading since the
* "new keys" might in fact be identical to the old ones,
* but tracking whether they are identical just for the
* sake of avoiding this message would be too much trouble.
*/
if (control != NULL) {
cfg_obj_log(control, named_g_lctx, ISC_LOG_WARNING,
"couldn't install new keys for "
"command channel %s: %s",
socktext, isc_result_totext(result));
} else {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL, ISC_LOG_WARNING,
"couldn't install new keys for "
"command channel %s: %s",
socktext, isc_result_totext(result));
}
2005-11-30 03:36:45 +00:00
}
/*
* Now, keep the old access list unless a new one can be made.
2001-03-27 00:45:13 +00:00
*/
if (control != NULL && type == isc_socktype_tcp) {
2001-08-03 05:56:22 +00:00
allow = cfg_tuple_get(control, "allow");
result = cfg_acl_fromconfig(allow, config, named_g_lctx,
aclconfctx, listener->mctx, 0,
&new_acl);
2001-08-03 05:56:22 +00:00
} else {
2001-08-03 18:28:48 +00:00
result = dns_acl_any(listener->mctx, &new_acl);
2001-08-03 05:56:22 +00:00
}
if (control != NULL) {
const cfg_obj_t *readonly = NULL;
readonly = cfg_tuple_get(control, "read-only");
if (!cfg_obj_isvoid(readonly)) {
listener->readonly = cfg_obj_asboolean(readonly);
}
}
2001-03-27 00:45:13 +00:00
if (result == ISC_R_SUCCESS) {
dns_acl_detach(&listener->acl);
dns_acl_attach(new_acl, &listener->acl);
dns_acl_detach(&new_acl);
/* XXXDCL say the old acl is still used? */
} else if (control != NULL) {
cfg_obj_log(control, named_g_lctx, ISC_LOG_WARNING,
2001-03-27 00:45:13 +00:00
"couldn't install new acl for "
"command channel %s: %s",
socktext, isc_result_totext(result));
} else {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL, ISC_LOG_WARNING,
"couldn't install new acl for "
"command channel %s: %s",
socktext, isc_result_totext(result));
}
2001-03-27 00:45:13 +00:00
if (result == ISC_R_SUCCESS && type == isc_socktype_unix) {
uint32_t perm, owner, group;
perm = cfg_obj_asuint32(cfg_tuple_get(control, "perm"));
owner = cfg_obj_asuint32(cfg_tuple_get(control, "owner"));
group = cfg_obj_asuint32(cfg_tuple_get(control, "group"));
result = ISC_R_SUCCESS;
if (listener->perm != perm || listener->owner != owner ||
2020-02-13 14:44:37 -08:00
listener->group != group)
{
result = isc_socket_permunix(&listener->address, perm,
owner, group);
}
if (result == ISC_R_SUCCESS) {
listener->perm = perm;
listener->owner = owner;
listener->group = group;
} else if (control != NULL) {
cfg_obj_log(control, named_g_lctx, ISC_LOG_WARNING,
"couldn't update ownership/permission for "
"command channel %s",
socktext);
}
}
2001-03-27 00:45:13 +00:00
*listenerp = listener;
}
static void
add_listener(named_controls_t *cp, controllistener_t **listenerp,
const cfg_obj_t *control, const cfg_obj_t *config,
isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx,
const char *socktext, isc_socktype_t type) {
2020-02-13 14:44:37 -08:00
isc_mem_t *mctx = cp->server->mctx;
controllistener_t *listener = NULL;
const cfg_obj_t *allow = NULL;
2020-02-13 14:44:37 -08:00
const cfg_obj_t *global_keylist = NULL;
const cfg_obj_t *control_keylist = NULL;
dns_acl_t *new_acl = NULL;
isc_result_t result = ISC_R_SUCCESS;
int pf;
2001-03-27 00:45:13 +00:00
listener = isc_mem_get(mctx, sizeof(*listener));
*listener = (controllistener_t){ .controls = cp,
.address = *addr,
.type = type };
isc_mem_attach(mctx, &listener->mctx);
Lock access to listener->connections as it is accessed from multiple threads with libuv. WARNING: ThreadSanitizer: data race Write of size 8 at 0x000000000001 by thread T1: #0 conn_reset bin/named/controlconf.c:574 #1 isc_nmhandle_detach netmgr/netmgr.c:1257 #2 isc__nm_uvreq_put netmgr/netmgr.c:1389 #3 tcp_send_cb netmgr/tcp.c:1030 #4 <null> <null> #5 <null> <null> Previous read of size 8 at 0x000000000001 by thread T2: #0 conn_reset bin/named/controlconf.c:574 #1 isc_nmhandle_detach netmgr/netmgr.c:1257 #2 control_recvmessage bin/named/controlconf.c:556 #3 recv_data lib/isccc/ccmsg.c:110 #4 isc__nm_tcp_shutdown netmgr/tcp.c:1161 #5 shutdown_walk_cb netmgr/netmgr.c:1511 #6 uv_walk <null> #7 process_queue netmgr/netmgr.c:656 #8 process_normal_queue netmgr/netmgr.c:582 #9 process_queues netmgr/netmgr.c:590 #10 async_cb netmgr/netmgr.c:548 #11 <null> <null> #12 <null> <null> Location is heap block of size 265 at 0x000000000017 allocated by thread T3: #0 malloc <null> #1 default_memalloc lib/isc/mem.c:713 #2 mem_get lib/isc/mem.c:622 #3 isc___mem_get lib/isc/mem.c:1044 #4 isc__mem_get lib/isc/mem.c:2432 #5 add_listener bin/named/controlconf.c:1127 #6 named_controls_configure bin/named/controlconf.c:1324 #7 load_configuration bin/named/server.c:9181 #8 run_server bin/named/server.c:9819 #9 dispatch lib/isc/task.c:1152 #10 run lib/isc/task.c:1344 #11 <null> <null> Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_nm_start netmgr/netmgr.c:232 #3 create_managers bin/named/main.c:909 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_nm_start netmgr/netmgr.c:232 #3 create_managers bin/named/main.c:909 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T3 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create pthreads/thread.c:73 #2 isc_taskmgr_create lib/isc/task.c:1434 #3 create_managers bin/named/main.c:915 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 SUMMARY: ThreadSanitizer: data race bin/named/controlconf.c:574 in conn_reset
2020-10-01 15:11:32 +10:00
isc_mutex_init(&listener->connections_lock);
ISC_LINK_INIT(listener, link);
ISC_LIST_INIT(listener->keys);
ISC_LIST_INIT(listener->connections);
isc_refcount_init(&listener->refs, 1);
2001-03-27 00:45:13 +00:00
/*
* Make the ACL.
*/
if (control != NULL && type == isc_socktype_tcp) {
const cfg_obj_t *readonly = NULL;
allow = cfg_tuple_get(control, "allow");
CHECK(cfg_acl_fromconfig(allow, config, named_g_lctx,
aclconfctx, mctx, 0, &new_acl));
readonly = cfg_tuple_get(control, "read-only");
if (!cfg_obj_isvoid(readonly)) {
listener->readonly = cfg_obj_asboolean(readonly);
}
} else {
CHECK(dns_acl_any(mctx, &new_acl));
}
dns_acl_attach(new_acl, &listener->acl);
dns_acl_detach(&new_acl);
if (config != NULL) {
get_key_info(config, control, &global_keylist,
&control_keylist);
}
2001-08-03 05:56:22 +00:00
if (control_keylist != NULL) {
controlkeylist_fromcfg(control_keylist, listener->mctx,
&listener->keys);
register_keys(control, global_keylist, &listener->keys,
listener->mctx, socktext);
} else {
result = get_rndckey(mctx, &listener->keys);
if (result != ISC_R_SUCCESS && control != NULL) {
cfg_obj_log(control, named_g_lctx, ISC_LOG_WARNING,
"couldn't install keys for "
2001-03-27 00:45:13 +00:00
"command channel %s: %s",
socktext, isc_result_totext(result));
}
2001-03-27 00:45:13 +00:00
}
pf = isc_sockaddr_pf(&listener->address);
if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) ||
Complete rewrite the BIND 9 build system The rewrite of BIND 9 build system is a large work and cannot be reasonable split into separate merge requests. Addition of the automake has a positive effect on the readability and maintainability of the build system as it is more declarative, it allows conditional and we are able to drop all of the custom make code that BIND 9 developed over the years to overcome the deficiencies of autoconf + custom Makefile.in files. This squashed commit contains following changes: - conversion (or rather fresh rewrite) of all Makefile.in files to Makefile.am by using automake - the libtool is now properly integrated with automake (the way we used it was rather hackish as the only official way how to use libtool is via automake - the dynamic module loading was rewritten from a custom patchwork to libtool's libltdl (which includes the patchwork to support module loading on different systems internally) - conversion of the unit test executor from kyua to automake parallel driver - conversion of the system test executor from custom make/shell to automake parallel driver - The GSSAPI has been refactored, the custom SPNEGO on the basis that all major KRB5/GSSAPI (mit-krb5, heimdal and Windows) implementations support SPNEGO mechanism. - The various defunct tests from bin/tests have been removed: bin/tests/optional and bin/tests/pkcs11 - The text files generated from the MD files have been removed, the MarkDown has been designed to be readable by both humans and computers - The xsl header is now generated by a simple sed command instead of perl helper - The <irs/platform.h> header has been removed - cleanups of configure.ac script to make it more simpler, addition of multiple macros (there's still work to be done though) - the tarball can now be prepared with `make dist` - the system tests are partially able to run in oot build Here's a list of unfinished work that needs to be completed in subsequent merge requests: - `make distcheck` doesn't yet work (because of system tests oot run is not yet finished) - documentation is not yet built, there's a different merge request with docbook to sphinx-build rst conversion that needs to be rebased and adapted on top of the automake - msvc build is non functional yet and we need to decide whether we will just cross-compile bind9 using mingw-w64 or fix the msvc build - contributed dlz modules are not included neither in the autoconf nor automake
2018-08-07 16:46:53 +02:00
#ifndef _WIN32
(pf == AF_UNIX && isc_net_probeunix() != ISC_R_SUCCESS) ||
#endif /* ifdef _WIN32 */
(pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS))
{
CHECK(ISC_R_FAMILYNOSUPPORT);
2001-03-27 00:45:13 +00:00
}
#if 0
/* XXX: no unix socket support yet */
if (type == isc_socktype_unix) {
isc_socket_cleanunix(&listener->address, false);
}
#endif
CHECK(isc_nm_listentcp(
named_g_netmgr, &listener->address, control_newconn, listener,
sizeof(controlconnection_t), 5, NULL, &listener->sock));
#if 0
/* XXX: no unix socket support yet */
if (type == isc_socktype_unix) {
listener->perm =
cfg_obj_asuint32(cfg_tuple_get(control, "perm"));
listener->owner =
cfg_obj_asuint32(cfg_tuple_get(control, "owner"));
listener->group =
cfg_obj_asuint32(cfg_tuple_get(control, "group"));
result = isc_socket_permunix(&listener->address, listener->perm,
listener->owner, listener->group);
}
#endif
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL, ISC_LOG_NOTICE,
"command channel listening on %s", socktext);
*listenerp = listener;
return;
2001-03-27 00:45:13 +00:00
cleanup:
isc_refcount_decrement(&listener->refs);
listener->exiting = true;
free_listener(listener);
2001-03-27 00:45:13 +00:00
if (control != NULL) {
cfg_obj_log(control, named_g_lctx, ISC_LOG_WARNING,
"couldn't add command channel %s: %s", socktext,
isc_result_totext(result));
} else {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL, ISC_LOG_NOTICE,
"couldn't add command channel %s: %s", socktext,
isc_result_totext(result));
2001-03-27 00:45:13 +00:00
}
*listenerp = NULL;
2001-03-27 00:45:13 +00:00
/* XXXDCL return error results? fail hard? */
}
isc_result_t
named_controls_configure(named_controls_t *cp, const cfg_obj_t *config,
2020-02-13 14:44:37 -08:00
cfg_aclconfctx_t *aclconfctx) {
controllistener_t *listener = NULL;
2001-03-27 00:45:13 +00:00
controllistenerlist_t new_listeners;
2020-02-13 14:44:37 -08:00
const cfg_obj_t *controlslist = NULL;
const cfg_listelt_t *element, *element2;
char socktext[ISC_SOCKADDR_FORMATSIZE];
2001-03-27 00:45:13 +00:00
ISC_LIST_INIT(new_listeners);
/*
* Get the list of named.conf 'controls' statements.
2001-03-27 00:45:13 +00:00
*/
(void)cfg_map_get(config, "controls", &controlslist);
/*
* Run through the new control channel list, noting sockets that
* are already being listened on and moving them to the new list.
*
* Identifying duplicate addr/port combinations is left to either
2001-03-27 00:45:13 +00:00
* the underlying config code, or to the bind attempt getting an
* address-in-use error.
*/
if (controlslist != NULL) {
for (element = cfg_list_first(controlslist); element != NULL;
2020-02-13 14:44:37 -08:00
element = cfg_list_next(element))
{
const cfg_obj_t *controls = NULL;
const cfg_obj_t *inetcontrols = NULL;
2001-03-27 00:45:13 +00:00
controls = cfg_listelt_value(element);
(void)cfg_map_get(controls, "inet", &inetcontrols);
if (inetcontrols == NULL) {
2001-03-27 00:45:13 +00:00
continue;
}
2001-03-27 00:45:13 +00:00
for (element2 = cfg_list_first(inetcontrols);
element2 != NULL;
2020-02-13 14:44:37 -08:00
element2 = cfg_list_next(element2))
{
const cfg_obj_t *control = NULL;
const cfg_obj_t *obj = NULL;
2020-02-13 14:44:37 -08:00
isc_sockaddr_t addr;
2001-03-27 00:45:13 +00:00
/*
* The parser handles BIND 8 configuration file
* syntax, so it allows unix phrases as well
* inet phrases with no keys{} clause.
*/
control = cfg_listelt_value(element2);
obj = cfg_tuple_get(control, "address");
addr = *cfg_obj_assockaddr(obj);
if (isc_sockaddr_getport(&addr) == 0) {
isc_sockaddr_setport(
&addr, NAMED_CONTROL_PORT);
}
2001-03-27 00:45:13 +00:00
isc_sockaddr_format(&addr, socktext,
2001-03-27 00:45:13 +00:00
sizeof(socktext));
isc_log_write(named_g_lctx,
NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL,
2001-03-27 00:45:13 +00:00
ISC_LOG_DEBUG(9),
"processing control channel %s",
socktext);
update_listener(cp, &listener, control, config,
&addr, aclconfctx, socktext,
isc_socktype_tcp);
2001-03-27 00:45:13 +00:00
if (listener != NULL) {
2001-03-27 00:45:13 +00:00
/*
* Remove the listener from the old
* list, so it won't be shut down.
*/
ISC_LIST_UNLINK(cp->listeners, listener,
link);
} else {
2001-03-27 00:45:13 +00:00
/*
* This is a new listener.
*/
add_listener(cp, &listener, control,
config, &addr, aclconfctx,
socktext,
isc_socktype_tcp);
}
if (listener != NULL) {
ISC_LIST_APPEND(new_listeners, listener,
link);
}
}
}
for (element = cfg_list_first(controlslist); element != NULL;
2020-02-13 14:44:37 -08:00
element = cfg_list_next(element))
{
const cfg_obj_t *controls = NULL;
const cfg_obj_t *unixcontrols = NULL;
controls = cfg_listelt_value(element);
(void)cfg_map_get(controls, "unix", &unixcontrols);
if (unixcontrols == NULL) {
continue;
}
cfg_obj_log(controls, named_g_lctx, ISC_LOG_ERROR,
"UNIX domain sockets not yet supported");
return (ISC_R_FAILURE);
#if 0
/* XXX: no unix domain socket support in netmgr */
for (element2 = cfg_list_first(unixcontrols);
element2 != NULL;
2020-02-13 14:44:37 -08:00
element2 = cfg_list_next(element2))
{
const cfg_obj_t *control = NULL;
const cfg_obj_t *path = NULL;
2020-02-13 14:44:37 -08:00
isc_sockaddr_t addr;
isc_result_t result;
/*
* The parser handles BIND 8 configuration file
* syntax, so it allows unix phrases as well
* inet phrases with no keys{} clause.
*/
control = cfg_listelt_value(element2);
path = cfg_tuple_get(control, "path");
result = isc_sockaddr_frompath(
&addr, cfg_obj_asstring(path));
if (result != ISC_R_SUCCESS) {
isc_log_write(
named_g_lctx,
NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL,
ISC_LOG_DEBUG(9),
"control channel '%s': %s",
cfg_obj_asstring(path),
isc_result_totext(result));
continue;
}
isc_log_write(named_g_lctx,
NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_CONTROL,
ISC_LOG_DEBUG(9),
"processing control channel '%s'",
cfg_obj_asstring(path));
update_listener(cp, &listener, control, config,
&addr, aclconfctx,
2008-01-18 23:46:58 +00:00
cfg_obj_asstring(path),
isc_socktype_unix);
if (listener != NULL) {
/*
* Remove the listener from the old
* list, so it won't be shut down.
*/
ISC_LIST_UNLINK(cp->listeners, listener,
link);
} else {
/*
* This is a new listener.
*/
add_listener(cp, &listener, control,
config, &addr, aclconfctx,
cfg_obj_asstring(path),
isc_socktype_unix);
}
2001-03-27 00:45:13 +00:00
if (listener != NULL) {
ISC_LIST_APPEND(new_listeners, listener,
link);
}
2001-03-27 00:45:13 +00:00
}
#endif
2001-03-27 00:45:13 +00:00
}
} else {
2001-08-03 05:56:22 +00:00
int i;
2001-08-06 11:28:21 +00:00
for (i = 0; i < 2; i++) {
2001-08-03 05:56:22 +00:00
isc_sockaddr_t addr;
if (i == 0) {
struct in_addr localhost;
if (isc_net_probeipv4() != ISC_R_SUCCESS) {
2001-08-03 05:56:22 +00:00
continue;
}
localhost.s_addr = htonl(INADDR_LOOPBACK);
isc_sockaddr_fromin(&addr, &localhost, 0);
2001-08-03 05:56:22 +00:00
} else {
if (isc_net_probeipv6() != ISC_R_SUCCESS) {
2001-08-03 05:56:22 +00:00
continue;
}
isc_sockaddr_fromin6(&addr, &in6addr_loopback,
0);
2001-08-03 05:56:22 +00:00
}
isc_sockaddr_setport(&addr, NAMED_CONTROL_PORT);
2001-08-03 05:56:22 +00:00
isc_sockaddr_format(&addr, socktext, sizeof(socktext));
2008-01-18 23:46:58 +00:00
update_listener(cp, &listener, NULL, NULL, &addr, NULL,
socktext, isc_socktype_tcp);
if (listener != NULL) {
2001-08-03 05:56:22 +00:00
/*
* Remove the listener from the old
* list, so it won't be shut down.
*/
ISC_LIST_UNLINK(cp->listeners, listener, link);
} else {
2001-08-03 05:56:22 +00:00
/*
* This is a new listener.
*/
add_listener(cp, &listener, NULL, NULL, &addr,
NULL, socktext, isc_socktype_tcp);
}
2001-08-03 05:56:22 +00:00
if (listener != NULL) {
ISC_LIST_APPEND(new_listeners, listener, link);
}
2001-08-03 05:56:22 +00:00
}
2001-03-27 00:45:13 +00:00
}
2001-08-03 05:56:22 +00:00
/*
* named_control_shutdown() will stop whatever is on the global
2001-08-03 05:56:22 +00:00
* listeners list, which currently only has whatever sockaddrs
* were in the previous configuration (if any) that do not
* remain in the current configuration.
*/
controls_shutdown(cp);
2001-08-03 05:56:22 +00:00
/*
* Put all of the valid listeners on the listeners list.
* Anything already on listeners in the process of shutting
* down will be taken care of by listen_done().
*/
ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link);
return (ISC_R_SUCCESS);
}
2001-03-27 00:45:13 +00:00
isc_result_t
2020-02-13 14:44:37 -08:00
named_controls_create(named_server_t *server, named_controls_t **ctrlsp) {
isc_mem_t *mctx = server->mctx;
isc_result_t result;
named_controls_t *controls = isc_mem_get(mctx, sizeof(*controls));
Lock access to control->symtab to prevent data race WARNING: ThreadSanitizer: data race Read of size 8 at 0x000000000001 by thread T1: #0 isccc_symtab_foreach lib/isccc/symtab.c:277:14 #1 isccc_cc_cleansymtab lib/isccc/cc.c:954:2 #2 control_recvmessage bin/named/controlconf.c:477:2 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Previous write of size 8 at 0x000000000001 by thread T2: #0 isccc_symtab_define lib/isccc/symtab.c:242:2 #1 isccc_cc_checkdup lib/isccc/cc.c:1026:11 #2 control_recvmessage bin/named/controlconf.c:478:11 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Location is heap block of size 190352 at 0x000000000011 allocated by main thread: #0 malloc <null> #1 isccc_symtab_create lib/isccc/symtab.c:76:18 #2 isccc_cc_createsymtab lib/isccc/cc.c:948:10 #3 named_controls_create bin/named/controlconf.c:1483:11 #4 named_server_create bin/named/server.c:10057:2 #5 setup bin/named/main.c:1256:2 #6 main bin/named/main.c:1523:2 Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 SUMMARY: ThreadSanitizer: data race lib/isccc/symtab.c:277:14 in isccc_symtab_foreach
2020-09-08 12:11:06 +10:00
*controls = (named_controls_t){
.server = server,
};
ISC_LIST_INIT(controls->listeners);
Lock access to control->symtab to prevent data race WARNING: ThreadSanitizer: data race Read of size 8 at 0x000000000001 by thread T1: #0 isccc_symtab_foreach lib/isccc/symtab.c:277:14 #1 isccc_cc_cleansymtab lib/isccc/cc.c:954:2 #2 control_recvmessage bin/named/controlconf.c:477:2 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Previous write of size 8 at 0x000000000001 by thread T2: #0 isccc_symtab_define lib/isccc/symtab.c:242:2 #1 isccc_cc_checkdup lib/isccc/cc.c:1026:11 #2 control_recvmessage bin/named/controlconf.c:478:11 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Location is heap block of size 190352 at 0x000000000011 allocated by main thread: #0 malloc <null> #1 isccc_symtab_create lib/isccc/symtab.c:76:18 #2 isccc_cc_createsymtab lib/isccc/cc.c:948:10 #3 named_controls_create bin/named/controlconf.c:1483:11 #4 named_server_create bin/named/server.c:10057:2 #5 setup bin/named/main.c:1256:2 #6 main bin/named/main.c:1523:2 Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 SUMMARY: ThreadSanitizer: data race lib/isccc/symtab.c:277:14 in isccc_symtab_foreach
2020-09-08 12:11:06 +10:00
isc_mutex_init(&controls->symtab_lock);
LOCK(&controls->symtab_lock);
result = isccc_cc_createsymtab(&controls->symtab);
Lock access to control->symtab to prevent data race WARNING: ThreadSanitizer: data race Read of size 8 at 0x000000000001 by thread T1: #0 isccc_symtab_foreach lib/isccc/symtab.c:277:14 #1 isccc_cc_cleansymtab lib/isccc/cc.c:954:2 #2 control_recvmessage bin/named/controlconf.c:477:2 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Previous write of size 8 at 0x000000000001 by thread T2: #0 isccc_symtab_define lib/isccc/symtab.c:242:2 #1 isccc_cc_checkdup lib/isccc/cc.c:1026:11 #2 control_recvmessage bin/named/controlconf.c:478:11 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Location is heap block of size 190352 at 0x000000000011 allocated by main thread: #0 malloc <null> #1 isccc_symtab_create lib/isccc/symtab.c:76:18 #2 isccc_cc_createsymtab lib/isccc/cc.c:948:10 #3 named_controls_create bin/named/controlconf.c:1483:11 #4 named_server_create bin/named/server.c:10057:2 #5 setup bin/named/main.c:1256:2 #6 main bin/named/main.c:1523:2 Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 SUMMARY: ThreadSanitizer: data race lib/isccc/symtab.c:277:14 in isccc_symtab_foreach
2020-09-08 12:11:06 +10:00
UNLOCK(&controls->symtab_lock);
if (result != ISC_R_SUCCESS) {
Lock access to control->symtab to prevent data race WARNING: ThreadSanitizer: data race Read of size 8 at 0x000000000001 by thread T1: #0 isccc_symtab_foreach lib/isccc/symtab.c:277:14 #1 isccc_cc_cleansymtab lib/isccc/cc.c:954:2 #2 control_recvmessage bin/named/controlconf.c:477:2 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Previous write of size 8 at 0x000000000001 by thread T2: #0 isccc_symtab_define lib/isccc/symtab.c:242:2 #1 isccc_cc_checkdup lib/isccc/cc.c:1026:11 #2 control_recvmessage bin/named/controlconf.c:478:11 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Location is heap block of size 190352 at 0x000000000011 allocated by main thread: #0 malloc <null> #1 isccc_symtab_create lib/isccc/symtab.c:76:18 #2 isccc_cc_createsymtab lib/isccc/cc.c:948:10 #3 named_controls_create bin/named/controlconf.c:1483:11 #4 named_server_create bin/named/server.c:10057:2 #5 setup bin/named/main.c:1256:2 #6 main bin/named/main.c:1523:2 Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 SUMMARY: ThreadSanitizer: data race lib/isccc/symtab.c:277:14 in isccc_symtab_foreach
2020-09-08 12:11:06 +10:00
isc_mutex_destroy(&controls->symtab_lock);
isc_mem_put(server->mctx, controls, sizeof(*controls));
return (result);
}
*ctrlsp = controls;
2001-03-27 00:45:13 +00:00
return (ISC_R_SUCCESS);
}
void
2020-02-13 14:44:37 -08:00
named_controls_destroy(named_controls_t **ctrlsp) {
named_controls_t *controls = *ctrlsp;
*ctrlsp = NULL;
REQUIRE(ISC_LIST_EMPTY(controls->listeners));
Lock access to control->symtab to prevent data race WARNING: ThreadSanitizer: data race Read of size 8 at 0x000000000001 by thread T1: #0 isccc_symtab_foreach lib/isccc/symtab.c:277:14 #1 isccc_cc_cleansymtab lib/isccc/cc.c:954:2 #2 control_recvmessage bin/named/controlconf.c:477:2 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Previous write of size 8 at 0x000000000001 by thread T2: #0 isccc_symtab_define lib/isccc/symtab.c:242:2 #1 isccc_cc_checkdup lib/isccc/cc.c:1026:11 #2 control_recvmessage bin/named/controlconf.c:478:11 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Location is heap block of size 190352 at 0x000000000011 allocated by main thread: #0 malloc <null> #1 isccc_symtab_create lib/isccc/symtab.c:76:18 #2 isccc_cc_createsymtab lib/isccc/cc.c:948:10 #3 named_controls_create bin/named/controlconf.c:1483:11 #4 named_server_create bin/named/server.c:10057:2 #5 setup bin/named/main.c:1256:2 #6 main bin/named/main.c:1523:2 Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 SUMMARY: ThreadSanitizer: data race lib/isccc/symtab.c:277:14 in isccc_symtab_foreach
2020-09-08 12:11:06 +10:00
LOCK(&controls->symtab_lock);
isccc_symtab_destroy(&controls->symtab);
Lock access to control->symtab to prevent data race WARNING: ThreadSanitizer: data race Read of size 8 at 0x000000000001 by thread T1: #0 isccc_symtab_foreach lib/isccc/symtab.c:277:14 #1 isccc_cc_cleansymtab lib/isccc/cc.c:954:2 #2 control_recvmessage bin/named/controlconf.c:477:2 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Previous write of size 8 at 0x000000000001 by thread T2: #0 isccc_symtab_define lib/isccc/symtab.c:242:2 #1 isccc_cc_checkdup lib/isccc/cc.c:1026:11 #2 control_recvmessage bin/named/controlconf.c:478:11 #3 recv_data lib/isccc/ccmsg.c:110:2 #4 read_cb lib/isc/netmgr/tcp.c:769:4 #5 <null> <null> Location is heap block of size 190352 at 0x000000000011 allocated by main thread: #0 malloc <null> #1 isccc_symtab_create lib/isccc/symtab.c:76:18 #2 isccc_cc_createsymtab lib/isccc/cc.c:948:10 #3 named_controls_create bin/named/controlconf.c:1483:11 #4 named_server_create bin/named/server.c:10057:2 #5 setup bin/named/main.c:1256:2 #6 main bin/named/main.c:1523:2 Thread T1 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 Thread T2 (running) created by main thread at: #0 pthread_create <null> #1 isc_thread_create lib/isc/pthreads/thread.c:73:8 #2 isc_nm_start lib/isc/netmgr/netmgr.c:215:3 #3 create_managers bin/named/main.c:909:15 #4 setup bin/named/main.c:1223:11 #5 main bin/named/main.c:1523:2 SUMMARY: ThreadSanitizer: data race lib/isccc/symtab.c:277:14 in isccc_symtab_foreach
2020-09-08 12:11:06 +10:00
UNLOCK(&controls->symtab_lock);
isc_mutex_destroy(&controls->symtab_lock);
isc_mem_put(controls->server->mctx, controls, sizeof(*controls));
}