diff options
author | Yang Tse <yangsita@gmail.com> | 2007-10-02 18:26:48 +0000 |
---|---|---|
committer | Yang Tse <yangsita@gmail.com> | 2007-10-02 18:26:48 +0000 |
commit | a15a88a4e674ac5bf625ff18204b3ea785d7f725 (patch) | |
tree | e2f364ab7be91949816f4732bd12f6e9c4712ec8 /ares_init.c | |
parent | 962f9c220abfd32db04d70aeb891e5c0e5bb390c (diff) | |
download | c-ares-a15a88a4e674ac5bf625ff18204b3ea785d7f725.tar.gz c-ares-a15a88a4e674ac5bf625ff18204b3ea785d7f725.tar.bz2 c-ares-a15a88a4e674ac5bf625ff18204b3ea785d7f725.zip |
Avoid a segfault when generating a DNS "Transaction ID" in internal
function init_id_key() under low memory conditions.
Diffstat (limited to 'ares_init.c')
-rw-r--r-- | ares_init.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/ares_init.c b/ares_init.c index c792f0a..e37ac7b 100644 --- a/ares_init.c +++ b/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) |