dovecot-2.2: lib-dns: The dns_lookup() call caused a crash upon ...

dovecot at dovecot.org dovecot at dovecot.org
Fri Oct 10 21:44:19 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/d15da5f1731e
changeset: 17938:d15da5f1731e
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sat Oct 11 00:43:38 2014 +0300
description:
lib-dns: The dns_lookup() call caused a crash upon a connect error, because dns_client_disconnect() can indirectly call itself recursively.
Solved by dropping the list of lookups from the client object before the
lookups are destroyed.

diffstat:

 src/lib-dns/dns-lookup.c |  26 +++++++++++++++-----------
 1 files changed, 15 insertions(+), 11 deletions(-)

diffs (52 lines):

diff -r 99dc3e3a3f75 -r d15da5f1731e src/lib-dns/dns-lookup.c
--- a/src/lib-dns/dns-lookup.c	Fri Oct 10 23:59:52 2014 +0300
+++ b/src/lib-dns/dns-lookup.c	Sat Oct 11 00:43:38 2014 +0300
@@ -56,18 +56,9 @@
 
 static void dns_client_disconnect(struct dns_client *client, const char *error)
 {
-	struct dns_lookup *lookup;
+	struct dns_lookup *lookup, *next;
 	struct dns_lookup_result result;
 
-	memset(&result, 0, sizeof(result));
-	result.ret = EAI_FAIL;
-	result.error = error;
-
-	while (client->head != NULL) {
-		lookup = client->head;
-		lookup->callback(&result, lookup->context);
-		dns_lookup_free(&lookup);
-	}
 	if (client->to_idle != NULL)
 		timeout_remove(&client->to_idle);
 	if (client->io != NULL)
@@ -79,6 +70,19 @@
 			i_error("close(%s) failed: %m", client->path);
 		client->fd = -1;
 	}
+
+	memset(&result, 0, sizeof(result));
+	result.ret = EAI_FAIL;
+	result.error = error;
+
+	lookup = client->head;
+	client->head = NULL;
+	while (lookup != NULL) {
+		next = lookup->next;
+		lookup->callback(&result, lookup->context);
+		dns_lookup_free(&lookup);
+		lookup = next;
+	}
 }
 
 static int dns_lookup_input_line(struct dns_lookup *lookup, const char *line)
@@ -242,7 +246,7 @@
 	i_free(lookup->ips);
 	if (client->deinit_client_at_free)
 		dns_client_deinit(&client);
-	else if (client->head == NULL) {
+	else if (client->head == NULL && client->fd != -1) {
 		client->to_idle = timeout_add(client->idle_timeout_msecs,
 					      dns_client_idle_timeout, client);
 	}


More information about the dovecot-cvs mailing list