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)
pull/400/head
bradh352 4 years ago
parent fa903fd7bb
commit df947034d9
  1. 2
      src/lib/ares_freeaddrinfo.c
  2. 12
      src/lib/ares_getaddrinfo.c

@ -51,6 +51,8 @@ void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *head)
void ares_freeaddrinfo(struct ares_addrinfo *ai) void ares_freeaddrinfo(struct ares_addrinfo *ai)
{ {
if (ai == NULL)
return;
ares__freeaddrinfo_cnames(ai->cnames); ares__freeaddrinfo_cnames(ai->cnames);
ares__freeaddrinfo_nodes(ai->nodes); ares__freeaddrinfo_nodes(ai->nodes);
ares_free(ai); ares_free(ai);

@ -544,11 +544,6 @@ static void host_callback(void *arg, int status, int timeouts,
{ {
addinfostatus = ares__parse_into_addrinfo(abuf, alen, hquery->ai); addinfostatus = ares__parse_into_addrinfo(abuf, alen, hquery->ai);
} }
else if (status == ARES_EDESTRUCTION)
{
end_hquery(hquery, status);
return;
}
if (!hquery->remaining) if (!hquery->remaining)
{ {
@ -566,6 +561,13 @@ static void host_callback(void *arg, int status, int timeouts,
{ {
next_lookup(hquery, status); 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 else
{ {
end_hquery(hquery, status); end_hquery(hquery, status);

Loading…
Cancel
Save