]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
Fixes from Dan.
authorWouter Wijngaards <wouter@NLnetLabs.nl>
Tue, 7 Dec 2010 12:49:17 +0000 (12:49 +0000)
committerWouter Wijngaards <wouter@NLnetLabs.nl>
Tue, 7 Dec 2010 12:49:17 +0000 (12:49 +0000)
15 files changed:
Changelog
dnssec.c
dnssec_sign.c
dnssec_verify.c
dnssec_zone.c
higher.c
host2str.c
keys.c
net.c
parse.c
resolver.c
rr.c
str2host.c
tsig.c
util.c

index de827a16db12bc1aeb7becf3cae0feccd4552b54..290a45a6eba539eff6cc0577aa471bf93b721d26 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -1,5 +1,8 @@
 1.6.8
        * Fix ldns zone, so that $TTL definition match RFC 2308.
+       * Fix lots of missing checks on allocation failures and parse of 
+         NSEC with many types and max parse length in hosts_frm_fp routine
+         and off by one in read_anchor_file routine (thanks Dan Kaminsky).
 
 1.6.7  2010-11-08
        * EXPERIMENTAL ecdsa implementation, please do not enable on real
index 5d394d1d745922afd5ec79f2d4e7b57935881c5b..cdbc19062d7edc0771e417140fb1fceab9b8af51 100644 (file)
--- a/dnssec.c
+++ b/dnssec.c
@@ -679,6 +679,7 @@ ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
 
        bm_len = i_type / 8 + 2;
        bitmap = LDNS_XMALLOC(uint8_t, bm_len);
+        if(!bitmap) return NULL;
        for (i = 0; i < bm_len; i++) {
                bitmap[i] = 0;
        }
@@ -700,6 +701,10 @@ ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
                                data = LDNS_XREALLOC(data,
                                                                 uint8_t,
                                                                 cur_data_size + cur_window_max + 3);
+                                if(!data) {
+                                        LDNS_FREE(bitmap);
+                                        return NULL;
+                                }
                                data[cur_data_size] = cur_window;
                                data[cur_data_size + 1] = cur_window_max + 1;
                                memcpy(data + cur_data_size + 2,
@@ -721,6 +726,10 @@ ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
                data = LDNS_XREALLOC(data,
                                                 uint8_t,
                                                 cur_data_size + cur_window_max + 3);
+                if(!data) {
+                        LDNS_FREE(bitmap);
+                        return NULL;
+                }
                data[cur_data_size] = cur_window;
                data[cur_data_size + 1] = cur_window_max + 1;
                memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
@@ -964,6 +973,10 @@ ldns_nsec3_hash_name(ldns_rdf *name,
 
        hashed_owner_str_len = salt_length + ldns_rdf_size(cann);
        hashed_owner_str = LDNS_XMALLOC(unsigned char, hashed_owner_str_len);
+        if(!hashed_owner_str) {
+               ldns_rdf_deep_free(cann);
+                return NULL;
+        }
        memcpy(hashed_owner_str, ldns_rdf_data(cann), ldns_rdf_size(cann));
        memcpy(hashed_owner_str + ldns_rdf_size(cann), salt, salt_length);
        ldns_rdf_deep_free(cann);
@@ -976,7 +989,6 @@ ldns_nsec3_hash_name(ldns_rdf *name,
                hashed_owner_str_len = salt_length + LDNS_SHA1_DIGEST_LENGTH;
                hashed_owner_str = LDNS_XMALLOC(unsigned char, hashed_owner_str_len);
                if (!hashed_owner_str) {
-                       fprintf(stderr, "Memory error\n");
                        return NULL;
                }
                memcpy(hashed_owner_str, hash, LDNS_SHA1_DIGEST_LENGTH);
@@ -990,6 +1002,9 @@ ldns_nsec3_hash_name(ldns_rdf *name,
 
        hashed_owner_b32 = LDNS_XMALLOC(char,
                   ldns_b32_ntop_calculate_size(hashed_owner_str_len) + 1);
+        if(!hashed_owner_b32) {
+                return NULL;
+        }
         hashed_owner_b32_len = (size_t) ldns_b32_ntop_extended_hex(
                 (uint8_t *) hashed_owner_str,
                 hashed_owner_str_len,
@@ -1048,11 +1063,20 @@ ldns_nsec3_add_param_rdfs(ldns_rr *rr,
        if (old) ldns_rdf_deep_free(old);
 
        salt_data = LDNS_XMALLOC(uint8_t, salt_length + 1);
+        if(!salt_data) {
+                /* no way to return error */
+                return;
+        }
        salt_data[0] = salt_length;
        memcpy(salt_data + 1, salt, salt_length);
        salt_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT,
                                                           salt_length + 1,
                                                           salt_data);
+        if(!salt_rdf) {
+                LDNS_FREE(salt_data);
+                /* no way to return error */
+                return;
+        }
 
        old = ldns_rr_set_rdf(rr, salt_rdf, 3);
        if (old) ldns_rdf_deep_free(old);
@@ -1228,6 +1252,7 @@ ldns_nsec3_salt_data(const ldns_rr *nsec3_rr)
        if (salt_rdf && ldns_rdf_size(salt_rdf) > 0) {
                salt_length = ldns_rdf_data(salt_rdf)[0];
                salt = LDNS_XMALLOC(uint8_t, salt_length);
+                if(!salt) return NULL;
                memcpy(salt, &ldns_rdf_data(salt_rdf)[1], salt_length);
                return salt;
        }
@@ -1538,25 +1563,35 @@ ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
                                         (const unsigned char **)&dsasig_data,
                                         sig_len);
        if (!dsasig) {
+                DSA_SIG_free(dsasig);
                return NULL;
        }
 
        dsasig_data = LDNS_XMALLOC(unsigned char, 41);
+        if(!dsasig_data) {
+                DSA_SIG_free(dsasig);
+                return NULL;
+        }
        dsasig_data[0] = 0;
        byte_offset = (size_t) (20 - BN_num_bytes(dsasig->r));
        if (byte_offset > 20) {
+                DSA_SIG_free(dsasig);
                return NULL;
        }
        memset(&dsasig_data[1], 0, byte_offset);
        BN_bn2bin(dsasig->r, &dsasig_data[1 + byte_offset]);
        byte_offset = (size_t) (20 - BN_num_bytes(dsasig->s));
        if (byte_offset > 20) {
+                DSA_SIG_free(dsasig);
                return NULL;
        }
        memset(&dsasig_data[21], 0, byte_offset);
        BN_bn2bin(dsasig->s, &dsasig_data[21 + byte_offset]);
 
        sigdata_rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, 41, dsasig_data);
+        if(!sigdata_rdf) {
+                LDNS_FREE(dsasig_data);
+        }
        DSA_SIG_free(dsasig);
 
        return sigdata_rdf;
index d571c93b26b2fddf9ec503960ee0e0bf6d20a46f..5d27761b94cd7ead307110f0a5df534eb9947af6 100644 (file)
@@ -319,10 +319,18 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
                return NULL;
        }
 
-
        sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
+        if(!sig) {
+               ldns_buffer_free(b64sig);
+               return NULL;
+        }
 
        data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
+        if(!data) {
+               ldns_buffer_free(b64sig);
+                DSA_SIG_free(sig);
+               return NULL;
+        }
 
        data[0] = 1;
        pad = 20 - (size_t) BN_num_bytes(sig->r);
@@ -343,6 +351,7 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
 
        ldns_buffer_free(b64sig);
        LDNS_FREE(data);
+        DSA_SIG_free(sig);
 
        return sigdata_rdf;
 }
index 11103dc25f95ef51eb321a28c577311a255e3f67..775f7de00e0da28627a71211bec13828c41c89e8 100644 (file)
@@ -19,6 +19,7 @@ ldns_dnssec_data_chain *
 ldns_dnssec_data_chain_new()
 {
        ldns_dnssec_data_chain *nc = LDNS_XMALLOC(ldns_dnssec_data_chain, 1);
+        if(!nc) return NULL;
        nc->rrset = NULL;
        nc->parent_type = 0;
        nc->parent = NULL;
@@ -428,6 +429,7 @@ ldns_dnssec_trust_tree_new()
 {
        ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
                                                                                   1);
+        if(!new_tree) return NULL;
        new_tree->rr = NULL;
        new_tree->rrset = NULL;
        new_tree->parent_count = 0;
@@ -494,6 +496,8 @@ ldns_dnssec_trust_tree_print_sm(FILE *out,
        if (!sibmap) {
                treedepth = ldns_dnssec_trust_tree_depth(tree);
                sibmap = malloc(treedepth);
+                if(!sibmap)
+                        return; /* mem err */
                memset(sibmap, 0, treedepth);
                mapset = true;
        }
@@ -651,6 +655,8 @@ ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
        size_t i, j;
 
        ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
+        if(!new_tree)
+                return NULL;
        
        if (data_chain && data_chain->rrset) {
                cur_rrset = data_chain->rrset;
index 91e5651cf3a5fd64d6fb0be5779e93225a66950e..e258c433b43e6acb8cc5d838634cc38295a74b7b 100644 (file)
@@ -11,6 +11,7 @@ ldns_dnssec_rrs_new()
 {
        ldns_dnssec_rrs *new_rrs;
        new_rrs = LDNS_MALLOC(ldns_dnssec_rrs);
+        if(!new_rrs) return NULL;
        new_rrs->rr = NULL;
        new_rrs->next = NULL;
        return new_rrs;
@@ -96,6 +97,7 @@ ldns_dnssec_rrsets_new()
 {
        ldns_dnssec_rrsets *new_rrsets;
        new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets);
+        if(!new_rrsets) return NULL;
        new_rrsets->rrs = NULL;
        new_rrsets->type = 0;
        new_rrsets->signatures = NULL;
@@ -555,6 +557,7 @@ ldns_dnssec_zone *
 ldns_dnssec_zone_new()
 {
        ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone);
+        if(!zone) return NULL;
        zone->soa = NULL;
        zone->names = NULL;
 
@@ -653,6 +656,7 @@ ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
 
        if (!zone->names) {
                zone->names = ldns_rbtree_create(ldns_dname_compare_v);
+                if(!zone->names) return LDNS_STATUS_MEM_ERR;
        }
 
        /* we need the original of the hashed name if this is
@@ -675,6 +679,7 @@ ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
                /* add */
                cur_name = ldns_dnssec_name_new_frm_rr(rr);
                cur_node = LDNS_MALLOC(ldns_rbnode_t);
+                if(!cur_node) return LDNS_STATUS_MEM_ERR;
                cur_node->key = ldns_rr_owner(rr);
                cur_node->data = cur_name;
                ldns_rbtree_insert(zone->names, cur_node);
index a4ab06f93d4ca818367c5182e06962b58d17b129..48e94defe431736e27ec347388995bb97cb3db73 100644 (file)
--- a/higher.c
+++ b/higher.c
@@ -173,8 +173,8 @@ ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
                return NULL;
        }
 
-       for(i = ldns_fget_token_l(fp, line, "\n", 0, line_nr);
-                       i > 0; i = ldns_fget_token_l(fp, line, "\n", 0, line_nr)) {
+       for(i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr);
+                       i > 0; i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr)) {
                /* # is comment */
                if (line[0] == '#') {
                        continue;
@@ -191,9 +191,9 @@ ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
                }
 
                ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
-               for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, 0);
+               for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN);
                                j > 0;
-                               j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, 0), cnt++) {
+                               j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN), cnt++) {
                        if (cnt == 0) {
                                /* the address */
                                if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, 
index 32ef8a5bad21941ebc91719385097f47e6b022b8..1031f211be172604e55d41096d12547825080134 100644 (file)
@@ -761,6 +761,10 @@ ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf)
 
        uint8_t *data = ldns_rdf_data(rdf);
 
+        if(ldns_rdf_size(rdf) == 0) {
+                output->_status = LDNS_STATUS_ERR;
+               return ldns_buffer_status(output);
+        }
        salt_length = data[0];
        /* from now there are variable length entries so remember pos */
        if (salt_length == 0 || ((size_t)salt_length)+1 > ldns_rdf_size(rdf)) {
@@ -887,6 +891,10 @@ ldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf)
        /* Subtract the size (2) of the number that specifies the length */
        size_t size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf) - 2);
        char *b64 = LDNS_XMALLOC(char, size);
+        if(!b64) {
+                output->_status = LDNS_STATUS_MEM_ERR;
+                return ldns_buffer_status(output);
+        }
 
        ldns_buffer_printf(output, "%u ", ldns_rdf_size(rdf) - 2);
 
@@ -932,16 +940,28 @@ ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf)
                        break;
                case 1:
                        gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
+                        if(!gateway_data)
+                                return LDNS_STATUS_MEM_ERR;
                        memcpy(gateway_data, &data[offset], LDNS_IP4ADDRLEN);
                        gateway = ldns_rdf_new(LDNS_RDF_TYPE_A, LDNS_IP4ADDRLEN , gateway_data);
                        offset += LDNS_IP4ADDRLEN;
+                        if(!gateway) {
+                                LDNS_FREE(gateway_data);
+                                return LDNS_STATUS_MEM_ERR;
+                        }
                        break;
                case 2:
                        gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
+                        if(!gateway_data)
+                                return LDNS_STATUS_MEM_ERR;
                        memcpy(gateway_data, &data[offset], LDNS_IP6ADDRLEN);
                        offset += LDNS_IP6ADDRLEN;
                        gateway =
                                ldns_rdf_new(LDNS_RDF_TYPE_AAAA, LDNS_IP6ADDRLEN, gateway_data);
+                        if(!gateway) {
+                                LDNS_FREE(gateway_data);
+                                return LDNS_STATUS_MEM_ERR;
+                        }
                        break;
                case 3:
                        status = ldns_wire2dname(&gateway, data, ldns_rdf_size(rdf), &offset);
@@ -955,8 +975,17 @@ ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf)
 
        public_key_size = ldns_rdf_size(rdf) - offset;
        public_key_data = LDNS_XMALLOC(uint8_t, public_key_size);
+        if(!public_key_data) {
+                ldns_rdf_free(gateway);
+                return LDNS_STATUS_MEM_ERR;
+        }
        memcpy(public_key_data, &data[offset], public_key_size);
        public_key = ldns_rdf_new(LDNS_RDF_TYPE_B64, public_key_size, public_key_data);
+        if(!public_key) {
+                LDNS_FREE(public_key_data);
+                ldns_rdf_free(gateway);
+                return LDNS_STATUS_MEM_ERR;
+        }
 
        ldns_buffer_printf(output, "%u %u %u ", precedence, gateway_type, algorithm);
     if (gateway)
@@ -1796,6 +1825,9 @@ ldns_buffer2str(ldns_buffer *buffer)
 
        tmp_str = ldns_buffer_export(buffer);
        str = LDNS_XMALLOC(char, strlen(tmp_str) + 1);
+        if(!str) {
+                return NULL;
+        }
        memcpy(str, tmp_str, strlen(tmp_str) + 1);
 
        return str;
diff --git a/keys.c b/keys.c
index e0fffc706849dd1fb763d2a2184b3d1437aaab85..6bc71bb339f897c19caf5412f705a45ebd69f8a2 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -95,9 +95,15 @@ ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm
        ldns_key *k;
 
        k = ldns_key_new();
+        if(!k) return LDNS_STATUS_MEM_ERR;
        k->_key.key = ENGINE_load_private_key(e, key_id, UI_OpenSSL(), NULL);
+        if(!k->_key.key) {
+                ldns_key_free(k);
+                return LDNS_STATUS_ERR;
+        }
        ldns_key_set_algorithm(k, (ldns_signing_algorithm) alg);
        if (!k->_key.key) {
+                ldns_key_free(k);
                return LDNS_STATUS_ENGINE_KEY_NOT_LOADED;
        } else {
                *key = k;
@@ -295,6 +301,8 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
 
        d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
        if (!k || !d) {
+                ldns_key_free(k);
+                LDNS_FREE(d);
                return LDNS_STATUS_MEM_ERR;
        }
 
@@ -310,9 +318,13 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
        if (ldns_fget_keyword_data_l(fp, "Private-key-format", ": ", d, "\n",
                                LDNS_MAX_LINELEN, line_nr) == -1) {
                /* no version information */
+                ldns_key_free(k);
+                LDNS_FREE(d);
                return LDNS_STATUS_SYNTAX_ERR;
        }
        if (strncmp(d, "v1.2", strlen(d)) != 0) {
+                ldns_key_free(k);
+                LDNS_FREE(d);
                return LDNS_STATUS_SYNTAX_VERSION_ERR;
        }
 
@@ -321,6 +333,8 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
        if (ldns_fget_keyword_data_l(fp, "Algorithm", ": ", d, "\n",
                                LDNS_MAX_LINELEN, line_nr) == -1) {
                /* no alg information */
+                ldns_key_free(k);
+                LDNS_FREE(d);
                return LDNS_STATUS_SYNTAX_ALG_ERR;
        }
 
@@ -465,6 +479,7 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
 #endif
                case 0:
                default:
+                       ldns_key_free(k);
                        return LDNS_STATUS_SYNTAX_ALG_ERR;
        }
        key_rr = ldns_key2rr(k);
@@ -522,7 +537,7 @@ ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr)
        buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
        rsa = RSA_new();
        if (!d || !rsa || !buf) {
-               return NULL;
+                goto error;
        }
 
        /* I could use functions again, but that seems an overkill,
@@ -639,8 +654,8 @@ ldns_key_new_frm_fp_dsa_l(FILE *f, int *line_nr)
        d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
        buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
        dsa = DSA_new();
-       if (!d || !dsa) {
-               return NULL;
+       if (!d || !dsa || !buf) {
+                goto error;
        }
 
        /* the line parser removes the () from the input... */
@@ -703,6 +718,7 @@ ldns_key_new_frm_fp_dsa_l(FILE *f, int *line_nr)
 error:
        LDNS_FREE(d);
        LDNS_FREE(buf);
+        DSA_free(dsa);
        return NULL;
 }
 
@@ -723,6 +739,9 @@ ldns_key_new_frm_fp_hmac_l(FILE *f, int *line_nr, size_t *hmac_size)
 
        d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
        buf = LDNS_XMALLOC(unsigned char, LDNS_MAX_LINELEN);
+        if(!d || !buf) {
+                goto error;
+        }
 
        if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
                goto error;
@@ -804,7 +823,12 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
                case LDNS_SIGN_RSASHA512:
 #ifdef HAVE_SSL
                        r = RSA_generate_key((int)size, RSA_F4, NULL, NULL);
+                        if(!r) {
+                               ldns_key_free(k);
+                               return NULL;
+                       }
                        if (RSA_check_key(r) != 1) {
+                               ldns_key_free(k);
                                return NULL;
                        }
 
@@ -816,9 +840,11 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
 #ifdef HAVE_SSL
                        d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL);
                        if (!d) {
+                               ldns_key_free(k);
                                return NULL;
                        }
                        if (DSA_generate_key(d) != 1) {
+                               ldns_key_free(k);
                                return NULL;
                        }
                        ldns_key_set_dsa_key(k, d);
@@ -834,6 +860,10 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
                        ldns_key_set_hmac_size(k, size);
 
                        hmac = LDNS_XMALLOC(unsigned char, size);
+                        if(!hmac) {
+                               ldns_key_free(k);
+                               return NULL;
+                        }
 #ifdef HAVE_SSL
                        if (RAND_bytes(hmac, (int) size) != 1) {
                                LDNS_FREE(hmac);
@@ -858,6 +888,10 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
                case LDNS_SIGN_ECC_GOST:
 #if defined(HAVE_SSL) && defined(USE_GOST)
                        ldns_key_set_evp_key(k, ldns_gen_gost_key());
+                        if(!k->_key.key) {
+                                ldns_key_free(k);
+                                return NULL;
+                        }
 #endif /* HAVE_SSL and USE_GOST */
                         break;
 #ifdef USE_ECDSA
@@ -867,13 +901,18 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
                                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
                         else if(alg == LDNS_ECDSAP384SHA384)
                                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
-                        if(!ec) return NULL;
+                        if(!ec) {
+                                ldns_key_free(k);
+                                return NULL;
+                        }
                         if(!EC_KEY_generate_key(ec)) {
+                                ldns_key_free(k);
                                 EC_KEY_free(ec);
                                 return NULL;
                         }
                         k->_key.key = EVP_PKEY_new();
                         if(!k->_key.key) {
+                                ldns_key_free(k);
                                 EC_KEY_free(ec);
                                 return NULL;
                         }
@@ -1156,6 +1195,7 @@ ldns_key *
 ldns_key_list_pop_key(ldns_key_list *key_list)
 {                               
         size_t key_count;
+        ldns_key** a;
         ldns_key *pop;
 
        if (!key_list) {
@@ -1170,8 +1210,11 @@ ldns_key_list_pop_key(ldns_key_list *key_list)
         pop = ldns_key_list_key(key_list, key_count);
         
         /* shrink the array */
-        key_list->_keys = LDNS_XREALLOC(
-                key_list->_keys, ldns_key *, key_count - 1);
+        a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1);
+        if(!a) {
+                return NULL;
+        }
+        key_list->_keys = a;
 
         ldns_key_list_set_key_count(key_list, key_count - 1);
 
@@ -1179,6 +1222,7 @@ ldns_key_list_pop_key(ldns_key_list *key_list)
 }       
 
 #ifdef HAVE_SSL
+/* data pointer must be large enough (LDNS_MAX_KEYLEN) */
 static bool
 ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size)
 {
@@ -1210,6 +1254,7 @@ ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size)
        return true;
 }
 
+/* data pointer must be large enough (LDNS_MAX_KEYLEN) */
 static bool
 ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
 {
@@ -1323,9 +1368,12 @@ ldns_key2rr(const ldns_key *k)
                        if (rsa) {
                                bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
                                if (!bin) {
+                                        ldns_rr_free(pubkey);
                                        return NULL;
                                }
                                if (!ldns_key_rsa2bin(bin, rsa, &size)) {
+                                       LDNS_FREE(bin);
+                                        ldns_rr_free(pubkey);
                                        return NULL;
                                }
                                RSA_free(rsa);
@@ -1342,9 +1390,12 @@ ldns_key2rr(const ldns_key *k)
                        if (dsa) {
                                bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
                                if (!bin) {
+                                        ldns_rr_free(pubkey);
                                        return NULL;
                                }
                                if (!ldns_key_dsa2bin(bin, dsa, &size)) {
+                                       LDNS_FREE(bin);
+                                        ldns_rr_free(pubkey);
                                        return NULL;
                                }
                                DSA_free(dsa);
@@ -1360,9 +1411,12 @@ ldns_key2rr(const ldns_key *k)
                        if (dsa) {
                                bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
                                if (!bin) {
+                                        ldns_rr_free(pubkey);
                                        return NULL;
                                }
                                if (!ldns_key_dsa2bin(bin, dsa, &size)) {
+                                       LDNS_FREE(bin);
+                                        ldns_rr_free(pubkey);
                                        return NULL;
                                }
                                DSA_free(dsa);
@@ -1375,9 +1429,13 @@ ldns_key2rr(const ldns_key *k)
                                LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
 #if defined(HAVE_SSL) && defined(USE_GOST)
                        bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
-                       if (!bin) 
+                       if (!bin) {
+                                ldns_rr_free(pubkey);
                                return NULL;
+                        }
                        if (!ldns_key_gost2bin(bin, k->_key.key, &size)) {
+                               LDNS_FREE(bin);
+                                ldns_rr_free(pubkey);
                                return NULL;
                        }
                        internal_data = 1;
@@ -1392,8 +1450,11 @@ ldns_key2rr(const ldns_key *k)
                         ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
                         EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
                         size = i2o_ECPublicKey(ec, NULL);
-                        if(!i2o_ECPublicKey(ec, &bin))
+                        if(!i2o_ECPublicKey(ec, &bin)) {
+                                EC_KEY_free(ec);
+                                ldns_rr_free(pubkey);
                                 return NULL;
+                        }
                        if(size > 1) {
                                /* move back one byte to shave off the 0x02
                                 * 'uncompressed' indicator that openssl made
@@ -1414,6 +1475,7 @@ ldns_key2rr(const ldns_key *k)
                case LDNS_SIGN_HMACSHA256:
                        bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k));
                        if (!bin) {
+                                ldns_rr_free(pubkey);
                                return NULL;
                        }
                        ldns_rr_push_rdf(pubkey,
@@ -1477,6 +1539,9 @@ ldns_read_anchor_file(const char *filename)
        size_t i = 0;
        ldns_rr *r;
        ldns_status status;
+        if(!line) {
+                return NULL;
+        }
 
        fp = fopen(filename, "r");
        if (!fp) {
@@ -1485,7 +1550,7 @@ ldns_read_anchor_file(const char *filename)
                return NULL;
        }
        
-       while ((c = fgetc(fp)) && i < LDNS_MAX_PACKETLEN && c != EOF) {
+       while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) {
                line[i] = c;
                i++;
        }
diff --git a/net.c b/net.c
index 1b067545a6ddd90fe3b9db9bd3449aea1cdca0d1..58aa67f195e18772f9e7f3d1acad6c0279e3bbcf 100644 (file)
--- a/net.c
+++ b/net.c
@@ -546,6 +546,10 @@ ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
        
        LDNS_FREE(wire);
        wire = LDNS_XMALLOC(uint8_t, wire_size);
+       if (!wire) {
+               *size = 0;
+               return NULL;
+       }
        bytes = 0;
 
        while (bytes < (ssize_t) wire_size) {
@@ -596,6 +600,10 @@ ldns_tcp_read_wire(int sockfd, size_t *size)
        
        LDNS_FREE(wire);
        wire = LDNS_XMALLOC(uint8_t, wire_size);
+       if (!wire) {
+               *size = 0;
+               return NULL;
+       }
        bytes = 0;
 
        while (bytes < (ssize_t) wire_size) {
@@ -644,6 +652,8 @@ ldns_tcp_send(uint8_t **result,  ldns_buffer *qbin, const struct sockaddr_storag
        /* resize accordingly */
        answer = (uint8_t*)LDNS_XREALLOC(answer, uint8_t *, (size_t)*answer_size);
        *result = answer;
+        if(!answer)
+                return LDNS_STATUS_MEM_ERR;
        return LDNS_STATUS_OK;
 }
 
@@ -805,6 +815,18 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class)
          * Is this necessary?
          */
         query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+        if(!query_wire) {
+                ldns_pkt_free(query);
+                LDNS_FREE(ns);
+#ifndef USE_WINSOCK
+               close(resolver->_socket);
+#else
+               closesocket(resolver->_socket);
+#endif
+               resolver->_socket = 0;
+
+                return LDNS_STATUS_MEM_ERR;
+        }
         status = ldns_pkt2buffer_wire(query_wire, query);
         if (status != LDNS_STATUS_OK) {
                 ldns_pkt_free(query);
diff --git a/parse.c b/parse.c
index 9e119751d4d4818e189fbe5d6c4a4f0a650d01ce..0487873520ecbe62c490bbf74cce84adb90b11e5 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -183,6 +183,8 @@ ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *
        char *fkeyword;
        ssize_t i;
 
+       if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
+               return -1;
        fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
        if(!fkeyword)
                return -1;
@@ -416,6 +418,8 @@ ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, c
        char *fkeyword;
        ssize_t i;
 
+       if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
+               return -1;
        fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
        if(!fkeyword)
                return -1; /* out of memory */
index db238c372518568812c9dd459b5ce5168e159baf..e49ab86fe09c9544d50463b573e165b2da8c4a33 100644 (file)
@@ -254,7 +254,9 @@ ldns_resolver_pop_nameserver(ldns_resolver *r)
        pop = nameservers[ns_count - 1];
 
        nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count - 1));
+        if(!nameservers) return NULL;
        rtt = LDNS_XREALLOC(rtt, size_t, (ns_count - 1));
+        if(!rtt) return NULL;
 
        ldns_resolver_set_nameservers(r, nameservers);
        ldns_resolver_set_rtt(r, rtt);
@@ -281,8 +283,12 @@ ldns_resolver_push_nameserver(ldns_resolver *r, ldns_rdf *n)
 
        /* make room for the next one */
        nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count + 1));
+        if(!nameservers)
+                return LDNS_STATUS_MEM_ERR;
        /* don't forget the rtt */
        rtt = LDNS_XREALLOC(rtt, size_t, (ns_count + 1));
+        if(!rtt)
+                return LDNS_STATUS_MEM_ERR;
 
        /* set the new value in the resolver */
        ldns_resolver_set_nameservers(r, nameservers);
diff --git a/rr.c b/rr.c
index 60ce49858cd593069883a1e5bfd28598b2c7a2d7..8e84fd615f6305bd5c2108b97a82cbef7f39f065 100644 (file)
--- a/rr.c
+++ b/rr.c
@@ -53,6 +53,10 @@ ldns_rr_new_frm_type(ldns_rr_type t)
        desc = ldns_rr_descript(t);
 
        rr->_rdata_fields = LDNS_XMALLOC(ldns_rdf *, ldns_rr_descriptor_minimum(desc));
+        if(!rr->_rdata_fields) {
+                LDNS_FREE(rr);
+                return NULL;
+        }
        for (i = 0; i < ldns_rr_descriptor_minimum(desc); i++) {
                rr->_rdata_fields[i] = NULL;
        }
@@ -144,6 +148,15 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
        rd = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
        b64 = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
        if (!new || !owner || !ttl || !clas || !rdata || !rr_buf || !rd_buf || !rd || !b64 ) {
+                ldns_rr_free(new);
+                LDNS_FREE(owner);
+                LDNS_FREE(ttl);
+                LDNS_FREE(clas);
+                LDNS_FREE(rdata);
+                LDNS_FREE(rr_buf);
+                LDNS_FREE(rd_buf);
+                LDNS_FREE(rd);
+                LDNS_FREE(b64);
                return LDNS_STATUS_MEM_ERR;
        }
 
@@ -196,6 +209,18 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                if (clas_val == 0) {
                        clas_val = LDNS_RR_CLASS_IN;
                        type = LDNS_XMALLOC(char, strlen(ttl) + 1);
+                        if(!type) {
+                                ldns_rr_free(new);
+                                LDNS_FREE(owner);
+                                LDNS_FREE(ttl);
+                                LDNS_FREE(clas);
+                                LDNS_FREE(rdata);
+                               ldns_buffer_free(rr_buf);
+                                LDNS_FREE(rd_buf);
+                                LDNS_FREE(rd);
+                                LDNS_FREE(b64);
+                                return LDNS_STATUS_MEM_ERR;
+                        }
                        strncpy(type, ttl, strlen(ttl) + 1);
                }
        } else {
@@ -218,6 +243,18 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                if (clas_val == 0) {
                        clas_val = LDNS_RR_CLASS_IN;
                        type = LDNS_XMALLOC(char, strlen(clas) + 1);
+                        if(!type) {
+                                ldns_rr_free(new);
+                                LDNS_FREE(owner);
+                                LDNS_FREE(ttl);
+                                LDNS_FREE(clas);
+                                LDNS_FREE(rdata);
+                               ldns_buffer_free(rr_buf);
+                                LDNS_FREE(rd_buf);
+                                LDNS_FREE(rd);
+                                LDNS_FREE(b64);
+                                return LDNS_STATUS_MEM_ERR;
+                        }
                        strncpy(type, clas, strlen(clas) + 1);
                }
        }
@@ -271,6 +308,19 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                if (prev) {
                        ldns_rdf_deep_free(*prev);
                        *prev = ldns_rdf_clone(ldns_rr_owner(new));
+                        if(!*prev) {
+                                LDNS_FREE(owner);
+                                LDNS_FREE(ttl);
+                                LDNS_FREE(clas);
+                                LDNS_FREE(type);
+                                LDNS_FREE(rdata);
+                                LDNS_FREE(rd);
+                                LDNS_FREE(rd_buf);
+                                LDNS_FREE(b64);
+                                ldns_buffer_free(rr_buf);
+                                ldns_rr_free(new);
+                                return LDNS_STATUS_MEM_ERR;
+                        }
                }
        } else {
                if (strlen(owner) == 0) {
@@ -283,6 +333,19 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                        } else {
                                ldns_rr_set_owner(new, ldns_dname_new_frm_str("."));
                        }
+                        if(!ldns_rr_owner(new)) {
+                                LDNS_FREE(owner);
+                                LDNS_FREE(ttl);
+                                LDNS_FREE(clas);
+                                LDNS_FREE(type);
+                                LDNS_FREE(rdata);
+                                LDNS_FREE(rd);
+                                LDNS_FREE(rd_buf);
+                                LDNS_FREE(b64);
+                                ldns_buffer_free(rr_buf);
+                                ldns_rr_free(new);
+                                return LDNS_STATUS_MEM_ERR;
+                        }
                } else {
                        owner_dname = ldns_dname_new_frm_str(owner);
                        if (!owner_dname) {
@@ -319,6 +382,19 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                        if (prev) {
                                ldns_rdf_deep_free(*prev);
                                *prev = ldns_rdf_clone(ldns_rr_owner(new));
+                                if(!*prev) {
+                                       LDNS_FREE(owner);
+                                       LDNS_FREE(ttl);
+                                       LDNS_FREE(clas);
+                                       LDNS_FREE(type);
+                                       LDNS_FREE(rdata);
+                                       LDNS_FREE(rd);
+                                       LDNS_FREE(rd_buf);
+                                       LDNS_FREE(b64);
+                                       ldns_buffer_free(rr_buf);
+                                       ldns_rr_free(new);
+                                       return LDNS_STATUS_MEM_ERR;
+                                }
                        }
                }
        }
@@ -420,8 +496,12 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                                c = ldns_bget_token(rd_buf, rd, delimiters, LDNS_MAX_RDFLEN);
                                                if (c == -1) {
                                                        /* something goes very wrong here */
-                                                       ldns_buffer_free(rd_buf);
-                                                       LDNS_FREE(rd);
+                                                        LDNS_FREE(rd);
+                                                        LDNS_FREE(b64);
+                                                        ldns_buffer_free(rd_buf);
+                                                        ldns_buffer_free(rr_buf);
+                                                        LDNS_FREE(rdata);
+                                                        ldns_rr_free(new);
                                                        return LDNS_STATUS_SYNTAX_RDATA_ERR;
                                                }
                                                hex_data_size = (uint16_t) atoi(rd);
@@ -429,8 +509,12 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                                hex_data_str = LDNS_XMALLOC(char, 2 * hex_data_size + 1);
                                                if (!hex_data_str) {
                                                        /* malloc error */
-                                                       ldns_buffer_free(rd_buf);
-                                                       LDNS_FREE(rd);
+                                                        LDNS_FREE(rd);
+                                                        LDNS_FREE(b64);
+                                                        ldns_buffer_free(rd_buf);
+                                                        ldns_buffer_free(rr_buf);
+                                                        LDNS_FREE(rdata);
+                                                        ldns_rr_free(new);
                                                        return LDNS_STATUS_SYNTAX_RDATA_ERR;
                                                }
                                                cur_hex_data_size = 0;
@@ -447,15 +531,55 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                                if (desc) {
                                                        size_t hex_pos = 0;
                                                        uint8_t *hex_data = LDNS_XMALLOC(uint8_t, hex_data_size + 2);
+                                                        ldns_status s;
+                                                        if(!hex_data) {
+                                                                LDNS_FREE(hex_data_str);
+                                                                LDNS_FREE(rd);
+                                                                LDNS_FREE(b64);
+                                                                ldns_buffer_free(rd_buf);
+                                                                ldns_buffer_free(rr_buf);
+                                                                LDNS_FREE(rdata);
+                                                                ldns_rr_free(new);
+                                                                return LDNS_STATUS_MEM_ERR;
+                                                        }
                                                        ldns_write_uint16(hex_data, hex_data_size);
                                                        ldns_hexstring_to_data(hex_data + 2, hex_data_str);
-                                                       (void) ldns_wire2rdf(new, hex_data,
+                                                       s = ldns_wire2rdf(new, hex_data,
                                                                         hex_data_size+2, &hex_pos);
+                                                        if(s != LDNS_STATUS_OK) {
+                                                                LDNS_FREE(hex_data_str);
+                                                                LDNS_FREE(rd);
+                                                                LDNS_FREE(b64);
+                                                                ldns_buffer_free(rd_buf);
+                                                                ldns_buffer_free(rr_buf);
+                                                                LDNS_FREE(rdata);
+                                                                ldns_rr_free(new);
+                                                                return s;
+                                                        }
                                                        LDNS_FREE(hex_data);
                                                } else {
                                                        r = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_HEX, hex_data_str);
+                                                        if(!r) {
+                                                                LDNS_FREE(hex_data_str);
+                                                                LDNS_FREE(rd);
+                                                                LDNS_FREE(b64);
+                                                                ldns_buffer_free(rd_buf);
+                                                                ldns_buffer_free(rr_buf);
+                                                                LDNS_FREE(rdata);
+                                                                ldns_rr_free(new);
+                                                                return LDNS_STATUS_MEM_ERR;
+                                                        }
                                                        ldns_rdf_set_type(r, LDNS_RDF_TYPE_UNKNOWN);
-                                                       ldns_rr_push_rdf(new, r);
+                                                       if(!ldns_rr_push_rdf(new, r)) {
+                                                                LDNS_FREE(hex_data_str);
+                                                                LDNS_FREE(rd);
+                                                                LDNS_FREE(b64);
+                                                                ldns_buffer_free(rd_buf);
+                                                                ldns_buffer_free(rr_buf);
+                                                                LDNS_FREE(rdata);
+                                                                ldns_rr_free(new);
+                                                                return LDNS_STATUS_MEM_ERR;
+                                                        }
                                                }
                                                LDNS_FREE(hex_data_str);
                                        } else {
@@ -500,6 +624,12 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                                                }
                                                        } else if (r && rd_strlen >= 1 && !ldns_dname_str_absolute(rd) && origin) {
                                                                if (ldns_dname_cat(r, origin) != LDNS_STATUS_OK) {
+                                                                       LDNS_FREE(rd);
+                                                                       LDNS_FREE(b64);
+                                                                       ldns_buffer_free(rd_buf);
+                                                                       ldns_buffer_free(rr_buf);
+                                                                       LDNS_FREE(rdata);
+                                                                       ldns_rr_free(new);
                                                                        return LDNS_STATUS_ERR;
                                                                }
                                                        }
@@ -865,6 +995,7 @@ ldns_rr_list *
 ldns_rr_list_new()
 {
        ldns_rr_list *rr_list = LDNS_MALLOC(ldns_rr_list);
+        if(!rr_list) return NULL;
        rr_list->_rr_count = 0;
        rr_list->_rr_capacity = 0;
        rr_list->_rrs = NULL;
@@ -1055,8 +1186,11 @@ ldns_rr_list_pop_rr(ldns_rr_list *rr_list)
 
        /* shrink the array */
        if(cap > LDNS_RRLIST_INIT && rr_count-1 <= cap/2) {
+                ldns_rr** a;
                cap /= 2;
-               rr_list->_rrs = LDNS_XREALLOC(rr_list->_rrs, ldns_rr *, cap);
+                a = LDNS_XREALLOC(rr_list->_rrs, ldns_rr *, cap);
+                if(!a) return NULL;
+               rr_list->_rrs = a;
                rr_list->_rr_capacity = cap;
        }
 
@@ -1358,6 +1492,8 @@ qsort_schwartz_rr_compare(const void *a, const void *b)
                        ldns_rr2canonical(canonical_a);
                        sa->transformed_object = ldns_buffer_new(ldns_rr_uncompressed_size(canonical_a));
                        if (ldns_rr2buffer_wire(sa->transformed_object, canonical_a, LDNS_SECTION_ANY) != LDNS_STATUS_OK) {
+                               ldns_buffer_free((ldns_buffer *)sa->transformed_object);
+                                sa->transformed_object = NULL;
                                ldns_rr_free(canonical_a);
                                return 0;
                        }
@@ -1368,6 +1504,10 @@ qsort_schwartz_rr_compare(const void *a, const void *b)
                        ldns_rr2canonical(canonical_b);
                        sb->transformed_object = ldns_buffer_new(ldns_rr_uncompressed_size(canonical_b));
                        if (ldns_rr2buffer_wire(sb->transformed_object, canonical_b, LDNS_SECTION_ANY) != LDNS_STATUS_OK) {
+                               ldns_buffer_free((ldns_buffer *)sa->transformed_object);
+                               ldns_buffer_free((ldns_buffer *)sb->transformed_object);
+                                sa->transformed_object = NULL;
+                                sb->transformed_object = NULL;
                                ldns_rr_free(canonical_b);
                                return 0;
                        }
@@ -1394,8 +1534,18 @@ ldns_rr_list_sort(ldns_rr_list *unsorted)
 
                sortables = LDNS_XMALLOC(struct ldns_schwartzian_compare_struct *,
                                         item_count);
+                if(!sortables) return; /* no way to return error */
                for (i = 0; i < item_count; i++) {
                        sortables[i] = LDNS_XMALLOC(struct ldns_schwartzian_compare_struct, 1);
+                        if(!sortables[i]) {
+                                /* free the allocated parts */
+                                while(i>0) {
+                                        i--;
+                                        LDNS_FREE(sortables[i]);
+                                }
+                                /* no way to return error */
+                                return;
+                        }
                        sortables[i]->original_object = ldns_rr_list_rr(unsorted, i);
                        sortables[i]->transformed_object = NULL;
                }
index f73b23d216e64e01a3f065ebb6c7a431b2020709..c4034537fdf97950f86b18c8fe20e68acf966a1f 100644 (file)
@@ -38,6 +38,7 @@ ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr)
        char *end = NULL;
        uint16_t *r;
        r = LDNS_MALLOC(uint16_t);
+        if(!r) return LDNS_STATUS_MEM_ERR;
 
        *r = htons((uint16_t)strtol((char *)shortstr, &end, 10));
 
@@ -48,7 +49,7 @@ ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr)
                *rd = ldns_rdf_new_frm_data(
                        LDNS_RDF_TYPE_INT16, sizeof(uint16_t), r);
                LDNS_FREE(r);
-               return LDNS_STATUS_OK;
+               return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
        }
 }
 
@@ -63,6 +64,7 @@ ldns_str2rdf_time(ldns_rdf **rd, const char *time)
 
        /* Try to scan the time... */
        r = (uint16_t*)LDNS_MALLOC(uint32_t);
+        if(!r) return LDNS_STATUS_MEM_ERR;
 
        memset(&tm, 0, sizeof(tm));
 
@@ -99,7 +101,7 @@ ldns_str2rdf_time(ldns_rdf **rd, const char *time)
                *rd = ldns_rdf_new_frm_data(
                        LDNS_RDF_TYPE_TIME, sizeof(uint32_t), r);
                LDNS_FREE(r);
-               return LDNS_STATUS_OK;
+               return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
        } else {
                /* handle it as 32 bits timestamp */
                l = htonl((uint32_t)strtol((char*)time, &end, 10));
@@ -111,7 +113,7 @@ ldns_str2rdf_time(ldns_rdf **rd, const char *time)
                        *rd = ldns_rdf_new_frm_data(
                                LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
                        LDNS_FREE(r);
-                       return LDNS_STATUS_OK;
+                       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
                }
        }
 
@@ -129,6 +131,9 @@ ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *salt_str)
 
        uint8_t *salt;
        uint8_t *data;
+       if(rd == NULL) {
+               return LDNS_STATUS_NULL;
+       }
 
        salt_length_str = strlen(salt_str);
        if (salt_length_str == 1 && salt_str[0] == '-') {
@@ -141,6 +146,9 @@ ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *salt_str)
        }
 
        salt = LDNS_XMALLOC(uint8_t, salt_length_str / 2);
+        if(!salt) {
+                return LDNS_STATUS_MEM_ERR;
+        }
        for (c = 0; c < salt_length_str; c += 2) {
                if (isxdigit((int) salt_str[c]) && isxdigit((int) salt_str[c+1])) {
                        salt[c/2] = (uint8_t) ldns_hexdigit_to_int(salt_str[c]) * 16 +
@@ -153,13 +161,17 @@ ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *salt_str)
        salt_length = (uint8_t) (salt_length_str / 2);
 
        data = LDNS_XMALLOC(uint8_t, 1 + salt_length);
+        if(!data) {
+               LDNS_FREE(salt);
+                return LDNS_STATUS_MEM_ERR;
+        }
        data[0] = salt_length;
        memcpy(&data[1], salt, salt_length);
        *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT, 1 + salt_length, data);
        LDNS_FREE(data);
        LDNS_FREE(salt);
 
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
@@ -178,7 +190,7 @@ ldns_str2rdf_period(ldns_rdf **rd,const char *period)
                *rd = ldns_rdf_new_frm_data(
                        LDNS_RDF_TYPE_PERIOD, sizeof(uint32_t), &p);
         }
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
@@ -189,6 +201,7 @@ ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr)
        uint32_t l;
 
        r = (uint16_t*)LDNS_MALLOC(uint32_t);
+        if(!r) return LDNS_STATUS_MEM_ERR;
        errno = 0; /* must set to zero before call,
                        note race condition on errno */
        if(*longstr == '-')
@@ -207,7 +220,7 @@ ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr)
                *rd = ldns_rdf_new_frm_data(
                        LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
                LDNS_FREE(r);
-               return LDNS_STATUS_OK;
+               return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
        }
 }
 
@@ -218,6 +231,7 @@ ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr)
        uint8_t *r = NULL;
 
        r = LDNS_MALLOC(uint8_t);
+        if(!r) return LDNS_STATUS_MEM_ERR;
 
        *r = (uint8_t)strtol((char*)bytestr, &end, 10);
 
@@ -228,7 +242,7 @@ ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr)
                *rd = ldns_rdf_new_frm_data(
                        LDNS_RDF_TYPE_INT8, sizeof(uint8_t), r);
                LDNS_FREE(r);
-               return LDNS_STATUS_OK;
+               return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
         }
 }
 
@@ -375,7 +389,7 @@ ldns_str2rdf_a(ldns_rdf **rd, const char *str)
                *rd = ldns_rdf_new_frm_data(
                        LDNS_RDF_TYPE_A, sizeof(address), &address);
         }
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
@@ -389,7 +403,7 @@ ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str)
                *rd = ldns_rdf_new_frm_data(
                        LDNS_RDF_TYPE_AAAA, sizeof(address) - 1, &address);
        }
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
@@ -403,6 +417,7 @@ ldns_str2rdf_str(ldns_rdf **rd, const char *str)
        }
 
        data = LDNS_XMALLOC(uint8_t, strlen(str) + 1);
+        if(!data) return LDNS_STATUS_MEM_ERR;
        i = 1;
        for (str_i = 0; str_i < strlen(str); str_i++) {
                if (str[str_i] == '\\') {
@@ -421,7 +436,7 @@ ldns_str2rdf_str(ldns_rdf **rd, const char *str)
        data[0] = i - 1;
        *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_STR, i, data);
        LDNS_FREE(data);
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
@@ -461,13 +476,20 @@ ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
        /* need ip addr and only ip addr for inet_pton */
        ip_str_len = (size_t) (strchr(my_str, '/') - my_str);
        my_ip_str = LDNS_XMALLOC(char, ip_str_len + 1);
+        if(!my_ip_str) return LDNS_STATUS_MEM_ERR;
        strncpy(my_ip_str, my_str, ip_str_len + 1);
        my_ip_str[ip_str_len] = '\0';
 
        if (family == 1) {
                /* ipv4 */
                afdpart = LDNS_XMALLOC(uint8_t, 4);
+                if(!afdpart) {
+                        LDNS_FREE(my_ip_str);
+                        return LDNS_STATUS_MEM_ERR;
+                }
                if (inet_pton(AF_INET, my_ip_str, afdpart) == 0) {
+                        LDNS_FREE(my_ip_str);
+                        LDNS_FREE(afdpart);
                        return LDNS_STATUS_INVALID_STR;
                }
                for (i = 0; i < 4; i++) {
@@ -478,7 +500,13 @@ ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
        } else if (family == 2) {
                /* ipv6 */
                afdpart = LDNS_XMALLOC(uint8_t, 16);
+                if(!afdpart) {
+                        LDNS_FREE(my_ip_str);
+                        return LDNS_STATUS_MEM_ERR;
+                }
                if (inet_pton(AF_INET6, my_ip_str, afdpart) == 0) {
+                        LDNS_FREE(my_ip_str);
+                        LDNS_FREE(afdpart);
                        return LDNS_STATUS_INVALID_STR;
                }
                for (i = 0; i < 16; i++) {
@@ -496,6 +524,10 @@ ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
        prefix = (uint8_t) atoi(my_str);
 
        data = LDNS_XMALLOC(uint8_t, 4 + afdlength);
+        if(!data) {
+               LDNS_FREE(my_ip_str);
+               return LDNS_STATUS_INVALID_STR;
+        }
        ldns_write_uint16(data, family);
        data[2] = prefix;
        data[3] = afdlength;
@@ -511,7 +543,7 @@ ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
        LDNS_FREE(data);
        LDNS_FREE(my_ip_str);
 
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
@@ -521,6 +553,9 @@ ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
        int16_t i;
 
        buffer = LDNS_XMALLOC(uint8_t, ldns_b64_ntop_calculate_size(strlen(str)));
+        if(!buffer) {
+                return LDNS_STATUS_MEM_ERR;
+        }
 
        i = (uint16_t)ldns_b64_pton((const char*)str, buffer,
                                                   ldns_b64_ntop_calculate_size(strlen(str)));
@@ -533,7 +568,7 @@ ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
        }
        LDNS_FREE(buffer);
 
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
@@ -544,11 +579,15 @@ ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
        /* first byte contains length of actual b32 data */
        uint8_t len = ldns_b32_pton_calculate_size(strlen(str));
        buffer = LDNS_XMALLOC(uint8_t, len + 1);
+        if(!buffer) {
+                return LDNS_STATUS_MEM_ERR;
+        }
        buffer[0] = len;
 
        i = ldns_b32_pton_extended_hex((const char*)str, strlen(str), buffer + 1,
                                                         ldns_b32_ntop_calculate_size(strlen(str)));
        if (i < 0) {
+                LDNS_FREE(buffer);
                return LDNS_STATUS_INVALID_B32_EXT;
        } else {
                *rd = ldns_rdf_new_frm_data(
@@ -556,7 +595,7 @@ ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
        }
        LDNS_FREE(buffer);
 
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
@@ -572,6 +611,9 @@ ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
                return LDNS_STATUS_LABEL_OVERFLOW;
        } else {
                t = LDNS_XMALLOC(uint8_t, (len / 2) + 1);
+                if(!t) {
+                        return LDNS_STATUS_MEM_ERR;
+                }
                t_orig = t;
                /* Now process octet by octet... */
                while (*str) {
@@ -585,6 +627,7 @@ ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
                                                if (isxdigit((int) *str)) {
                                                        *t += ldns_hexdigit_to_int(*str) * i;
                                                } else {
+                                                        LDNS_FREE(t_orig);
                                                        return LDNS_STATUS_ERR;
                                                }
                                                ++str;
@@ -598,7 +641,7 @@ ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
                                            t_orig);
                LDNS_FREE(t_orig);
        }
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
@@ -610,7 +653,7 @@ ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
        ssize_t c;
        uint16_t cur_type;
        size_t type_count = 0;
-       ldns_rr_type type_list[1024];
+       ldns_rr_type type_list[65536];
        if(!token) return LDNS_STATUS_MEM_ERR;
        if(rd == NULL) {
                LDNS_FREE(token);
@@ -630,6 +673,11 @@ ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
        }
 
        while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1 && c != 0) {
+                if(type_count >= sizeof(type_list)) {
+                       LDNS_FREE(str_buf);
+                       LDNS_FREE(token);
+                        return LDNS_STATUS_ERR;
+                }
                cur_type = ldns_get_rr_type_by_name(token);
                type_list[type_count] = cur_type;
                type_count++;
@@ -641,7 +689,7 @@ ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
 
        LDNS_FREE(token);
        ldns_buffer_free(str_buf);
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
@@ -652,7 +700,7 @@ ldns_str2rdf_type(ldns_rdf **rd, const char *str)
        /* ldns_rr_type is a 16 bit value */
        *rd = ldns_rdf_new_frm_data(
                LDNS_RDF_TYPE_TYPE, sizeof(uint16_t), &type);
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
@@ -663,7 +711,7 @@ ldns_str2rdf_class(ldns_rdf **rd, const char *str)
        /* class is 16 bit */
        *rd = ldns_rdf_new_frm_data(
                LDNS_RDF_TYPE_CLASS, sizeof(uint16_t), &klass);
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 /* An certificate alg field can either be specified as a 8 bits number
@@ -942,6 +990,9 @@ east:
        }
 
        data = LDNS_XMALLOC(uint8_t, 16);
+        if(!data) {
+                return LDNS_STATUS_MEM_ERR;
+        }
        data[0] = 0;
        data[1] = 0;
        data[1] = ((size_b << 4) & 0xf0) | (size_e & 0x0f);
@@ -955,7 +1006,7 @@ east:
                LDNS_RDF_TYPE_LOC, 16, data);
 
        LDNS_FREE(data);
-       return LDNS_STATUS_OK;
+       return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
 }
 
 ldns_status
diff --git a/tsig.c b/tsig.c
index 40839609523ea6256c5f7d0be8bc0db8985c5d9b..b2882f1ea722ba874837a16ded9e02ae5a859bed 100644 (file)
--- a/tsig.c
+++ b/tsig.c
@@ -66,6 +66,9 @@ ldns_tsig_prepare_pkt_wire(uint8_t *wire, size_t wire_len, size_t *result_len)
 
        ldns_status status;
 
+        if(wire_len < LDNS_HEADER_SIZE) {
+                return LDNS_STATUS_WIRE_INCOMPLETE_HEADER;
+        }
        /* fake parse the wire */
        qd_count = LDNS_QDCOUNT(wire);
        an_count = LDNS_ANCOUNT(wire);
@@ -115,6 +118,9 @@ ldns_tsig_prepare_pkt_wire(uint8_t *wire, size_t wire_len, size_t *result_len)
 
        *result_len = pos;
        wire2 = LDNS_XMALLOC(uint8_t, *result_len);
+        if(!wire2) {
+                return NULL;
+        }
        memcpy(wire2, wire, *result_len);
 
        ldns_write_uint16(wire2 + LDNS_ARCOUNT_OFF, ar_count);
@@ -330,7 +336,6 @@ ldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const ch
 #endif /* HAVE_SSL */
 
 #ifdef HAVE_SSL
-/* TODO: memory :p */
 ldns_status
 ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data,
        uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac)
@@ -361,11 +366,19 @@ ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_dat
        ldns_rdf *time_signed_rdf = NULL;
 
        algorithm_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, algorithm_name);
+        if(!key_name_rdf || !algorithm_rdf) {
+                status = LDNS_STATUS_MEM_ERR;
+                goto clean;
+        }
 
        /* eww don't have create tsigtime rdf yet :( */
        /* bleh :p */
        if (gettimeofday(&tv_time_signed, NULL) == 0) {
                time_signed = LDNS_XMALLOC(uint8_t, 6);
+                if(!time_signed) {
+                        status = LDNS_STATUS_MEM_ERR;
+                        goto clean;
+                }
                ldns_write_uint64_as_uint48(time_signed,
                                (uint64_t)tv_time_signed.tv_sec);
        } else {
@@ -374,6 +387,11 @@ ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_dat
        }
 
        time_signed_rdf = ldns_rdf_new(LDNS_RDF_TYPE_TSIGTIME, 6, time_signed);
+        if(!time_signed_rdf) {
+                LDNS_FREE(time_signed);
+                status = LDNS_STATUS_MEM_ERR;
+                goto clean;
+        }
 
        fudge_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, fudge);
 
@@ -383,6 +401,11 @@ ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_dat
 
        other_data_rdf = ldns_native2rdf_int16_data(0, NULL);
 
+        if(!fudge_rdf || !orig_id_rdf || !error_rdf || !other_data_rdf) {
+                status = LDNS_STATUS_MEM_ERR;
+                goto clean;
+        }
+
        if (ldns_pkt2wire(&pkt_wire, pkt, &pkt_wire_len) != LDNS_STATUS_OK) {
                status = LDNS_STATUS_ERR;
                goto clean;
@@ -400,6 +423,10 @@ ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_dat
 
        /* Create the TSIG RR */
        tsig_rr = ldns_rr_new();
+        if(!tsig_rr) {
+                status = LDNS_STATUS_MEM_ERR;
+                goto clean;
+        }
        ldns_rr_set_owner(tsig_rr, key_name_rdf);
        ldns_rr_set_class(tsig_rr, LDNS_RR_CLASS_ANY);
        ldns_rr_set_type(tsig_rr, LDNS_RR_TYPE_TSIG);
@@ -418,6 +445,7 @@ ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_dat
        return status;
 
   clean:
+       LDNS_FREE(pkt_wire);
        ldns_rdf_free(key_name_rdf);
        ldns_rdf_free(algorithm_rdf);
        ldns_rdf_free(time_signed_rdf);
diff --git a/util.c b/util.c
index 3b446ba7198caaa1af23d41d7ff0e2897ab0aa69..5870bb6edcf6747f3a11db09ac90312a7c015d04 100644 (file)
--- a/util.c
+++ b/util.c
@@ -270,6 +270,9 @@ ldns_init_random(FILE *fd, unsigned int size)
        }
 
        seed = LDNS_XMALLOC(uint8_t, size);
+        if(!seed) {
+               return 1;
+        }
 
        if (!fd) {
                if ((rand_f = fopen("/dev/urandom", "r")) == NULL) {