diff options
-rw-r--r-- | ares/CHANGES | 2 | ||||
-rw-r--r-- | ares/ares_cancel.c | 7 | ||||
-rw-r--r-- | ares/ares_destroy.c | 42 | ||||
-rw-r--r-- | ares/ares_init.c | 54 |
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. */ |