aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ares/CHANGES2
-rw-r--r--ares/ares_cancel.c7
-rw-r--r--ares/ares_destroy.c42
-rw-r--r--ares/ares_init.c54
4 files changed, 70 insertions, 35 deletions
diff --git a/ares/CHANGES b/ares/CHANGES
index 770f037eb..378a81816 100644
--- a/ares/CHANGES
+++ b/ares/CHANGES
@@ -2,6 +2,8 @@
* November 6
+- Yang Tse removed a couple of potential zero size memory allocations.
+
- Andreas Rieke fixed the line endings in the areslib.dsp file that I (Daniel)
broke in the 1.3.2 release. We should switch to a system where that file is
auto-generated. We could rip some code for that from curl...
diff --git a/ares/ares_cancel.c b/ares/ares_cancel.c
index 8e3efa3b2..9641dab20 100644
--- a/ares/ares_cancel.c
+++ b/ares/ares_cancel.c
@@ -39,7 +39,10 @@ void ares_cancel(ares_channel channel)
channel->queries = NULL;
if (!(channel->flags & ARES_FLAG_STAYOPEN))
{
- for (i = 0; i < channel->nservers; i++)
- ares__close_sockets(channel, &channel->servers[i]);
+ if (channel->servers)
+ {
+ for (i = 0; i < channel->nservers; i++)
+ ares__close_sockets(channel, &channel->servers[i]);
+ }
}
}
diff --git a/ares/ares_destroy.c b/ares/ares_destroy.c
index b7a21e9e3..fd243c30a 100644
--- a/ares/ares_destroy.c
+++ b/ares/ares_destroy.c
@@ -25,23 +25,37 @@ void ares_destroy(ares_channel channel)
int i;
struct query *query;
- for (i = 0; i < channel->nservers; i++)
- ares__close_sockets(channel, &channel->servers[i]);
- free(channel->servers);
- for (i = 0; i < channel->ndomains; i++)
- free(channel->domains[i]);
- free(channel->domains);
+ if (!channel)
+ return;
+
+ if (channel->servers) {
+ for (i = 0; i < channel->nservers; i++)
+ ares__close_sockets(channel, &channel->servers[i]);
+ free(channel->servers);
+ }
+
+ if (channel->domains) {
+ for (i = 0; i < channel->ndomains; i++)
+ free(channel->domains[i]);
+ free(channel->domains);
+ }
+
if(channel->sortlist)
free(channel->sortlist);
- free(channel->lookups);
- while (channel->queries)
- {
- query = channel->queries;
- channel->queries = query->next;
- query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
+
+ if (channel->lookups)
+ free(channel->lookups);
+
+ while (channel->queries) {
+ query = channel->queries;
+ channel->queries = query->next;
+ query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
+ if (query->tcpbuf)
free(query->tcpbuf);
+ if (query->skip_server)
free(query->skip_server);
- free(query);
- }
+ free(query);
+ }
+
free(channel);
}
diff --git a/ares/ares_init.c b/ares/ares_init.c
index a9fa8fbc1..7246bc484 100644
--- a/ares/ares_init.c
+++ b/ares/ares_init.c
@@ -125,7 +125,9 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
channel->queries = NULL;
channel->domains = NULL;
channel->sortlist = NULL;
+ channel->servers = NULL;
channel->sock_state_cb = NULL;
+ channel->sock_state_cb_data = NULL;
/* Initialize configuration by each of the four sources, from highest
* precedence to lowest.
@@ -140,7 +142,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
if (status != ARES_SUCCESS)
{
/* Something failed; clean up memory we may have allocated. */
- if (channel->nservers != -1)
+ if (channel->servers)
free(channel->servers);
if (channel->domains)
{
@@ -214,12 +216,16 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
/* Copy the servers, if given. */
if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
{
- channel->servers =
- malloc(options->nservers * sizeof(struct server_state));
- if (!channel->servers && options->nservers != 0)
- return ARES_ENOMEM;
- for (i = 0; i < options->nservers; i++)
- channel->servers[i].addr = options->servers[i];
+ /* Avoid zero size allocations at any cost */
+ if (options->nservers > 0)
+ {
+ channel->servers =
+ malloc(options->nservers * sizeof(struct server_state));
+ if (!channel->servers)
+ return ARES_ENOMEM;
+ for (i = 0; i < options->nservers; i++)
+ channel->servers[i].addr = options->servers[i];
+ }
channel->nservers = options->nservers;
}
@@ -228,16 +234,20 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
*/
if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
{
- channel->domains = malloc(options->ndomains * sizeof(char *));
- if (!channel->domains && options->ndomains != 0)
- return ARES_ENOMEM;
- for (i = 0; i < options->ndomains; i++)
- {
- channel->ndomains = i;
- channel->domains[i] = strdup(options->domains[i]);
- if (!channel->domains[i])
- return ARES_ENOMEM;
- }
+ /* Avoid zero size allocations at any cost */
+ if (options->ndomains > 0)
+ {
+ channel->domains = malloc(options->ndomains * sizeof(char *));
+ if (!channel->domains)
+ return ARES_ENOMEM;
+ for (i = 0; i < options->ndomains; i++)
+ {
+ channel->ndomains = i;
+ channel->domains[i] = strdup(options->domains[i]);
+ if (!channel->domains[i])
+ return ARES_ENOMEM;
+ }
+ }
channel->ndomains = options->ndomains;
}
@@ -711,7 +721,6 @@ static int init_by_defaults(ares_channel channel)
if (gethostname(hostname, sizeof(hostname)) == -1
|| !strchr(hostname, '.'))
{
- channel->domains = malloc(0);
channel->ndomains = 0;
}
else
@@ -940,6 +949,7 @@ static int set_search(ares_channel channel, const char *str)
for(n=0; n < channel->ndomains; n++)
free(channel->domains[n]);
free(channel->domains);
+ channel->domains = NULL;
channel->ndomains = -1;
}
@@ -955,8 +965,14 @@ static int set_search(ares_channel channel, const char *str)
n++;
}
+ if (!n)
+ {
+ channel->ndomains = 0;
+ return ARES_SUCCESS;
+ }
+
channel->domains = malloc(n * sizeof(char *));
- if (!channel->domains && n)
+ if (!channel->domains)
return ARES_ENOMEM;
/* Now copy the domains. */