From 4eefa351cc5549a2cebb45d274f10249e31f6945 Mon Sep 17 00:00:00 2001 From: Mukund Sivaraman Date: Tue, 3 Feb 2015 11:42:58 +0530 Subject: [PATCH] Fix a leak of query fetchlock (#38454) 4052. [bug] Fix a leak of query fetchlock. [RT #38454] --- CHANGES | 2 ++ bin/named/client.c | 28 ++++++++++++++++++---------- bin/named/query.c | 8 +++++++- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 8f7a9d78b8..d476ed1c6d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +4052. [bug] Fix a leak of query fetchlock. [RT #38454] + 4051. [bug] Fix a leak of pthread_mutexattr_t. [RT #38454] 4050. [cleanup] Silence occasional spurious "duplicate query" log diff --git a/bin/named/client.c b/bin/named/client.c index 143a6a1494..326f7250ae 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -556,6 +556,17 @@ exit_check(ns_client_t *client) { INSIST(client->recursionquota == NULL); INSIST(!ISC_QLINK_LINKED(client, ilink)); + if (manager != NULL) { + LOCK(&manager->listlock); + ISC_LIST_UNLINK(manager->clients, client, link); + LOCK(&manager->lock); + if (manager->exiting && + ISC_LIST_EMPTY(manager->clients)) + destroy_manager = ISC_TRUE; + UNLOCK(&manager->lock); + UNLOCK(&manager->listlock); + } + ns_query_free(client); isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); isc_event_free((isc_event_t **)&client->sendevent); @@ -575,16 +586,6 @@ exit_check(ns_client_t *client) { } dns_message_destroy(&client->message); - if (manager != NULL) { - LOCK(&manager->listlock); - ISC_LIST_UNLINK(manager->clients, client, link); - LOCK(&manager->lock); - if (manager->exiting && - ISC_LIST_EMPTY(manager->clients)) - destroy_manager = ISC_TRUE; - UNLOCK(&manager->lock); - UNLOCK(&manager->listlock); - } /* * Detaching the task must be done after unlinking from @@ -605,6 +606,13 @@ exit_check(ns_client_t *client) { isc_mem_stats(client->mctx, stderr); INSIST(0); } + + /* + * Destroy the fetchlock mutex that was created in + * ns_query_init(). + */ + DESTROYLOCK(&client->query.fetchlock); + isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); } diff --git a/bin/named/query.c b/bin/named/query.c index b592f742e9..cc9d7c4cc3 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -632,6 +632,10 @@ ns_query_init(ns_client_t *client) { client->query.timerset = ISC_FALSE; client->query.rpz_st = NULL; client->query.qname = NULL; + /* + * This mutex is destroyed when the client is destroyed in + * exit_check(). + */ result = isc_mutex_init(&client->query.fetchlock); if (result != ISC_R_SUCCESS) return (result); @@ -652,8 +656,10 @@ ns_query_init(ns_client_t *client) { return (result); } result = query_newnamebuf(client); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { query_freefreeversions(client, ISC_TRUE); + DESTROYLOCK(&client->query.fetchlock); + } return (result); }