Commit a32738e3 authored by Andreas Gustafsson's avatar Andreas Gustafsson
Browse files

352. [bug] Race condition in dns_client_t startup could cause

                        an assertion failure.
parent 0b7ce4ac
352. [bug] Race condition in dns_client_t startup could cause
an assertion failure.
351. [bug] Constructing a response with rcode SERVFAIL to a TSIG
signed query could crash the server.
......
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: client.c,v 1.102 2000/07/17 23:19:14 gson Exp $ */
/* $Id: client.c,v 1.103 2000/07/26 17:39:09 gson Exp $ */
#include <config.h>
......@@ -163,6 +163,8 @@ static void clientmgr_destroy(ns_clientmgr_t *manager);
static isc_boolean_t exit_check(ns_client_t *client);
static void ns_client_endrequest(ns_client_t *client);
static void ns_client_checkactive(ns_client_t *client);
static void client_start(isc_task_t *task, isc_event_t *event);
static void client_request(isc_task_t *task, isc_event_t *event);
/*
* Enter the inactive state.
......@@ -431,6 +433,45 @@ exit_check(ns_client_t *client) {
return (ISC_TRUE);
}
/*
* The client's task has received the client's control event
* as part of the startup process.
*/
static void
client_start(isc_task_t *task, isc_event_t *event) {
ns_client_t *client = (ns_client_t *) event->ev_arg;
isc_result_t result;
INSIST(task == client->task);
UNUSED(task);
if (TCP_CLIENT(client)) {
client_accept(client);
} else {
result = dns_dispatch_addrequest(client->dispatch,
client->task,
client_request,
client,
&client->dispentry);
if (result != ISC_R_SUCCESS) {
ns_client_log(client,
DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT,
ISC_LOG_DEBUG(3),
"dns_dispatch_addrequest() "
"failed: %s",
isc_result_totext(result));
/*
* Not much we can do here but log the failure;
* the client will effectively go idle.
*/
}
}
}
/*
* The client's task has received a shutdown event.
*/
......@@ -565,14 +606,14 @@ client_senddone(isc_task_t *task, isc_event_t *event) {
ns_client_t *client;
isc_socketevent_t *sevent = (isc_socketevent_t *) event;
UNUSED(task);
REQUIRE(sevent != NULL);
REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE);
client = sevent->ev_arg;
REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(task == client->task);
UNUSED(task);
CTRACE("senddone");
if (sevent->result != ISC_R_SUCCESS)
......@@ -1195,6 +1236,9 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp)
client->recursionquota = NULL;
client->interface = NULL;
client->peeraddr_valid = ISC_FALSE;
ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL,
DNS_EVENT_CLIENTCONTROL, client_start, client, client,
NULL, NULL);
ISC_LINK_INIT(client, link);
client->list = NULL;
......@@ -1272,7 +1316,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
INSIST(client->state == NS_CLIENTSTATE_READY);
INSIST(client->naccepts == 1);
client->naccepts--;
......@@ -1529,6 +1573,7 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
LOCK(&manager->lock);
for (i = 0; i < n; i++) {
isc_event_t *ev;
/*
* Allocate a client. First try to get a recycled one;
* if that fails, make a new one.
......@@ -1553,30 +1598,16 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
client->attributes |= NS_CLIENTATTR_TCP;
isc_socket_attach(ifp->tcpsocket,
&client->tcplistener);
client_accept(client);
} else {
dns_dispatch_attach(ifp->udpdispatch,
&client->dispatch);
result = dns_dispatch_addrequest(client->dispatch,
client->task,
client_request,
client,
&client->dispentry);
if (result != ISC_R_SUCCESS) {
ns_client_log(client,
DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT,
ISC_LOG_DEBUG(3),
"dns_dispatch_addrequest() "
"failed: %s",
isc_result_totext(result));
isc_task_shutdown(client->task);
break;
}
}
client->manager = manager;
ISC_LIST_APPEND(manager->active, client, link);
client->list = &manager->active;
ev = &client->ctlevent;
isc_task_send(client->task, &ev);
}
if (i != 0) {
/*
......
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: client.h,v 1.37 2000/06/22 21:49:38 tale Exp $ */
/* $Id: client.h,v 1.38 2000/07/26 17:39:11 gson Exp $ */
#ifndef NAMED_CLIENT_H
#define NAMED_CLIENT_H 1
......@@ -122,6 +122,7 @@ struct ns_client {
isc_sockaddr_t peeraddr;
isc_boolean_t peeraddr_valid;
struct in6_pktinfo pktinfo;
isc_event_t ctlevent;
ISC_LINK(ns_client_t) link;
/*
* The list 'link' is part of, or NULL if not on any list.
......
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: events.h,v 1.24 2000/06/22 21:55:38 tale Exp $ */
/* $Id: events.h,v 1.25 2000/07/26 17:39:12 gson Exp $ */
#ifndef DNS_EVENTS_H
#define DNS_EVENTS_H 1
......@@ -52,6 +52,7 @@
#define DNS_EVENT_NOTIFYSENDTOADDR (ISC_EVENTCLASS_DNS + 23)
#define DNS_EVENT_ZONE (ISC_EVENTCLASS_DNS + 24)
#define DNS_EVENT_ZONESTARTXFRIN (ISC_EVENTCLASS_DNS + 25)
#define DNS_EVENT_CLIENTCONTROL (ISC_EVENTCLASS_DNS + 26)
#define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0)
#define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535)
......
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