aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Tse <yangsita@gmail.com>2007-10-02 18:26:48 +0000
committerYang Tse <yangsita@gmail.com>2007-10-02 18:26:48 +0000
commit94162d62aca15e3d900513a8f37bc84a12db5d16 (patch)
treefc7f1799b49ea6e1e7b11684e2b82932fd173e39
parent059707be320e993e7ee047e1e728ce9d6e67e4f7 (diff)
Avoid a segfault when generating a DNS "Transaction ID" in internal
function init_id_key() under low memory conditions.
-rw-r--r--ares/CHANGES4
-rw-r--r--ares/ares_init.c25
2 files changed, 22 insertions, 7 deletions
diff --git a/ares/CHANGES b/ares/CHANGES
index 2a94acf9e..f7a9ca6cf 100644
--- a/ares/CHANGES
+++ b/ares/CHANGES
@@ -1,9 +1,13 @@
Changelog for the c-ares project
* October 2 2007 (Daniel Stenberg)
+
- ares_strerror() segfaulted if the input error number was out of the currently
supported range.
+- Yang Tse: Avoid a segfault when generating a DNS "Transaction ID" in
+ internal function init_id_key() under low memory conditions.
+
* September 28 2007 (Daniel Stenberg)
- Bumped version to 1.5.0 for next release and soname bumped to 2 due to ABI
diff --git a/ares/ares_init.c b/ares/ares_init.c
index c792f0a84..e37ac7b6e 100644
--- a/ares/ares_init.c
+++ b/ares/ares_init.c
@@ -75,7 +75,7 @@ static int config_nameserver(struct server_state **servers, int *nservers,
static int set_search(ares_channel channel, const char *str);
static int set_options(ares_channel channel, const char *str);
static const char *try_option(const char *p, const char *q, const char *opt);
-static void init_id_key(rc4_key* key,int key_data_len);
+static int init_id_key(rc4_key* key,int key_data_len);
#ifndef WIN32
static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
@@ -189,6 +189,18 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
ares_strerror(status)));
}
+
+ /* Generate random key */
+
+ if (status == ARES_SUCCESS) {
+ status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
+ if (status == ARES_SUCCESS)
+ channel->next_id = ares__generate_new_id(&channel->id_key);
+ else
+ DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
+ ares_strerror(status)));
+ }
+
if (status != ARES_SUCCESS)
{
/* Something failed; clean up memory we may have allocated. */
@@ -228,10 +240,6 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
server->is_broken = 0;
}
- init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
-
- channel->next_id = ares__generate_new_id(&channel->id_key);
-
*channelptr = channel;
return ARES_SUCCESS;
}
@@ -1345,7 +1353,7 @@ static void randomize_key(unsigned char* key,int key_data_len)
}
}
-static void init_id_key(rc4_key* key,int key_data_len)
+static int init_id_key(rc4_key* key,int key_data_len)
{
unsigned char index1;
unsigned char index2;
@@ -1354,6 +1362,9 @@ static void init_id_key(rc4_key* key,int key_data_len)
unsigned char *key_data_ptr = 0;
key_data_ptr = calloc(1,key_data_len);
+ if (!key_data_ptr)
+ return ARES_ENOMEM;
+
randomize_key(key->state,key_data_len);
state = &key->state[0];
for(counter = 0; counter < 256; counter++)
@@ -1372,7 +1383,7 @@ static void init_id_key(rc4_key* key,int key_data_len)
index1 = (index1 + 1) % key_data_len;
}
free(key_data_ptr);
-
+ return ARES_SUCCESS;
}
short ares__generate_new_id(rc4_key* key)