From 718b30d03992eb408d057559fb277da51a2414b8 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] (cherry picked from commit 4eefa351cc5549a2cebb45d274f10249e31f6945) --- 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 5537cdb383..7e8d6696a1 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] 4049. [bug] CDS and CDNSKEY had the wrong attributes. [RT #38491] diff --git a/bin/named/client.c b/bin/named/client.c index 7a60c986be..4d09c3bf3d 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -546,6 +546,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); @@ -565,16 +576,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 @@ -595,6 +596,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 353f5d2457..9ad4bfb4be 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -618,6 +618,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); @@ -638,8 +642,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); }