From df947034d9606471e59e95c79723aa58f125ad89 Mon Sep 17 00:00:00 2001 From: bradh352 Date: Tue, 2 Mar 2021 18:15:49 -0500 Subject: [PATCH] Null deref if ares_getaddrinfo() is terminated with ares_destroy() ares_freeaddrinfo() was not checking for a Null ptr during cleanup of an aborted query. Once that was resolved it uncovered another possible issue with multiple simultaneous underlying queries being outstanding and possibly prematurely cleaning up the handle. Reported By: Michael Kourlas Fix By: Brad House (@bradh352) --- src/lib/ares_freeaddrinfo.c | 2 ++ src/lib/ares_getaddrinfo.c | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/lib/ares_freeaddrinfo.c b/src/lib/ares_freeaddrinfo.c index 128f5daec..d8891bbf8 100644 --- a/src/lib/ares_freeaddrinfo.c +++ b/src/lib/ares_freeaddrinfo.c @@ -51,6 +51,8 @@ void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *head) void ares_freeaddrinfo(struct ares_addrinfo *ai) { + if (ai == NULL) + return; ares__freeaddrinfo_cnames(ai->cnames); ares__freeaddrinfo_nodes(ai->nodes); ares_free(ai); diff --git a/src/lib/ares_getaddrinfo.c b/src/lib/ares_getaddrinfo.c index dd2f43121..6d607b195 100644 --- a/src/lib/ares_getaddrinfo.c +++ b/src/lib/ares_getaddrinfo.c @@ -544,11 +544,6 @@ static void host_callback(void *arg, int status, int timeouts, { addinfostatus = ares__parse_into_addrinfo(abuf, alen, hquery->ai); } - else if (status == ARES_EDESTRUCTION) - { - end_hquery(hquery, status); - return; - } if (!hquery->remaining) { @@ -566,6 +561,13 @@ static void host_callback(void *arg, int status, int timeouts, { next_lookup(hquery, status); } + else if (status == ARES_EDESTRUCTION) + { + /* NOTE: Could also be ARES_EDESTRUCTION. We need to only call this + * once all queries (there can be multiple for getaddrinfo) are + * terminated. */ + end_hquery(hquery, status); + } else { end_hquery(hquery, status);