]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
Assertion error fix! Bug #391
authorWillem Toorop <willem@NLnetLabs.nl>
Mon, 29 Aug 2011 14:02:00 +0000 (14:02 +0000)
committerWillem Toorop <willem@NLnetLabs.nl>
Mon, 29 Aug 2011 14:02:00 +0000 (14:02 +0000)
12 files changed:
dnssec.c
dnssec_sign.c
dnssec_verify.c
error.c
higher.c
host2str.c
host2wire.c
ldns/error.h
rr.c
rr_functions.c
tsig.c
update.c

index 7dc2ca6c880a1580713624c18d333cd5c83e28ff..661608b88949d54ae5d0c2c23666914e53e54c5c 100644 (file)
--- a/dnssec.c
+++ b/dnssec.c
@@ -565,7 +565,14 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
        ldns_rr_push_rdf(ds, tmp);
 
        /* copy the algorithm field */
-       ldns_rr_push_rdf(ds, ldns_rdf_clone( ldns_rr_rdf(key, 2))); 
+       if ((tmp = ldns_rr_rdf(key, 2)) == NULL) {
+               LDNS_FREE(digest);
+               ldns_buffer_free(data_buf);
+               ldns_rr_free(ds);
+               return NULL;
+       } else {
+               ldns_rr_push_rdf(ds, ldns_rdf_clone( tmp )); 
+       }
 
        /* digest hash type */
        sha1hash = (uint8_t)h;
@@ -1209,8 +1216,8 @@ ldns_nsec3_algorithm(const ldns_rr *nsec3_rr)
        if (nsec3_rr && 
              (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
               ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
-           && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 0)) > 0
-           ) {
+           && (ldns_rr_rdf(nsec3_rr, 0) != NULL)
+           && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 0)) > 0) {
                return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 0));
        }
        return 0;
@@ -1222,8 +1229,8 @@ ldns_nsec3_flags(const ldns_rr *nsec3_rr)
        if (nsec3_rr && 
              (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
               ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
-           && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 1)) > 0
-           ) {
+           && (ldns_rr_rdf(nsec3_rr, 1) != NULL)
+           && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 1)) > 0) {
                return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 1));
        }
        return 0;
@@ -1241,8 +1248,8 @@ ldns_nsec3_iterations(const ldns_rr *nsec3_rr)
        if (nsec3_rr &&
              (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
               ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
-           && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 2)) > 0
-           ) {
+           && (ldns_rr_rdf(nsec3_rr, 2) != NULL)
+           && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 2)) > 0) {
                return ldns_rdf2native_int16(ldns_rr_rdf(nsec3_rr, 2));
        }
        return 0;
@@ -1375,7 +1382,11 @@ ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name)
        bool result;
 
        if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC) {
-               nsec_next = ldns_rdf_clone(ldns_rr_rdf(nsec, 0));
+               if (ldns_rr_rdf(nsec, 0) != NULL) {
+                       nsec_next = ldns_rdf_clone(ldns_rr_rdf(nsec, 0));
+               } else {
+                       return false;
+               }
        } else if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC3) {
                hash_next = ldns_nsec3_next_owner(nsec);
                next_hash_str = ldns_rdf2str(hash_next);
index 8ae1a45ddebd6a4e0830e94e3a75466b21856f55..fcb1aae514876c0a7c76f406c8af9f0088b33c52 100644 (file)
@@ -709,9 +709,9 @@ ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
        /* did the caller actually set it? if not,
         * fall back to default ttl
         */
-       if (soa && soa->rrs && soa->rrs->rr) {
-               nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(
-                                                    soa->rrs->rr, 6));
+       if (soa && soa->rrs && soa->rrs->rr
+                       && (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) {
+               nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
        } else {
                nsec_ttl = LDNS_DEFAULT_TTL;
        }
@@ -795,9 +795,9 @@ ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
        /* did the caller actually set it? if not,
         * fall back to default ttl
         */
-       if (soa && soa->rrs && soa->rrs->rr) {
-               nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(
-                                                    soa->rrs->rr, 6));
+       if (soa && soa->rrs && soa->rrs->rr
+                       && ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
+               nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
        } else {
                nsec_ttl = LDNS_DEFAULT_TTL;
        }
index 52c654c3606f4d546db488e991c1463f03b27595..008ba8ad361a5f2376d250311d73661a63bf96d2 100644 (file)
@@ -391,7 +391,9 @@ ldns_dnssec_build_data_chain(ldns_resolver *res,
                }
        }
 
-       if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
+       if (signatures && ldns_rr_list_rr_count(signatures) > 0
+                       && ldns_rr_rd_count(ldns_rr_list_rr(signatures, 0))
+                               > 7) {
                key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7);
        }
 
@@ -1749,6 +1751,10 @@ ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
        ldns_rdf *wildcard_name;
        ldns_rdf *wildcard_chopped;
        ldns_rdf *wildcard_chopped_tmp;
+       
+       if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
+               return;
+       }
 
        orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
        label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
@@ -1788,7 +1794,15 @@ ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
 static ldns_status
 ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
 {
-       uint8_t sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
+       uint8_t sig_algo;
+       
+       if (rrsig == NULL) {
+               return LDNS_STATUS_CRYPTO_NO_RRSIG;
+       }
+       if (ldns_rr_rdf(rrsig, 1) == NULL) {
+               return LDNS_STATUS_MALFORMED_RRSIG;
+       }
+       sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
        /* check for known and implemented algo's now (otherwise 
         * the function could return a wrong error
         */
@@ -1807,16 +1821,23 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
 #ifdef USE_GOST
        case LDNS_ECC_GOST:
 #endif
-               if (ldns_rdf2buffer_wire(rawsig_buf, 
-                   ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+               if (ldns_rr_rdf(rrsig, 8) == NULL) {
+                       return LDNS_STATUS_MALFORMED_RRSIG;
+               }
+               if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
+                               != LDNS_STATUS_OK) {
                        return LDNS_STATUS_MEM_ERR;
                }
                break;
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
                /* EVP takes rfc2459 format, which is a tad longer than dns format */
-               if (ldns_convert_dsa_rrsig_rdf2asn1(rawsig_buf, 
-                       ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+               if (ldns_rr_rdf(rrsig, 8) == NULL) {
+                       return LDNS_STATUS_MALFORMED_RRSIG;
+               }
+               if (ldns_convert_dsa_rrsig_rdf2asn1(
+                                       rawsig_buf, ldns_rr_rdf(rrsig, 8)) 
+                               != LDNS_STATUS_OK) {
                        /*
                          if (ldns_rdf2buffer_wire(rawsig_buf,
                          ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
@@ -1829,8 +1850,12 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
         case LDNS_ECDSAP384SHA384:
                 /* EVP produces an ASN prefix on the signature, which is
                  * not used in the DNS */
-               if (ldns_convert_ecdsa_rrsig_rdf2asn1(rawsig_buf, 
-                       ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+               if (ldns_rr_rdf(rrsig, 8) == NULL) {
+                       return LDNS_STATUS_MALFORMED_RRSIG;
+               }
+               if (ldns_convert_ecdsa_rrsig_rdf2asn1(
+                                       rawsig_buf, ldns_rr_rdf(rrsig, 8))
+                               != LDNS_STATUS_OK) {
                        return LDNS_STATUS_MEM_ERR;
                 }
                 break;
@@ -1936,7 +1961,15 @@ static ldns_status
 ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
        ldns_rr* rrsig, ldns_rr* key)
 {
-       uint8_t sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
+       uint8_t sig_algo;
+       
+       if (rrsig == NULL) {
+               return LDNS_STATUS_CRYPTO_NO_RRSIG;
+       }
+       if (ldns_rr_rdf(rrsig, 1) == NULL) {
+               return LDNS_STATUS_MALFORMED_RRSIG;
+       }
+       sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
 
        /* before anything, check if the keytags match */
        if (ldns_calc_keytag(key)
@@ -1948,8 +1981,12 @@ ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
 
                /* put the key-data in a buffer, that's the third rdf, with
                 * the base64 encoded key data */
-               if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3)) 
-                       != LDNS_STATUS_OK) {
+               if (ldns_rr_rdf(rrsig, 3) == NULL) {
+                       ldns_buffer_free(key_buf);
+                       return LDNS_STATUS_MALFORMED_RRSIG;
+               }
+               if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(rrsig, 3))
+                               != LDNS_STATUS_OK) {
                        ldns_buffer_free(key_buf); 
                        /* returning is bad might screw up
                           good keys later in the list
@@ -1957,7 +1994,11 @@ ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
                        return LDNS_STATUS_ERR;
                }
 
-               if (sig_algo == ldns_rdf2native_int8(ldns_rr_rdf(key, 2))) {
+               if (ldns_rr_rdf(rrsig, 2) == NULL) {
+                       result = LDNS_STATUS_MALFORMED_RRSIG;
+               }
+               else if (sig_algo == ldns_rdf2native_int8(
+                                       ldns_rr_rdf(rrsig, 2))) {
                        result = ldns_verify_rrsig_buffers(rawsig_buf, 
                                verify_buf, key_buf, sig_algo);
                } else {
diff --git a/error.c b/error.c
index ff240dcc82a15c47118708dab59ca89f14f0e668..82c8522549e513779ca126731a66118e943a1e89 100644 (file)
--- a/error.c
+++ b/error.c
@@ -88,6 +88,7 @@ ldns_lookup_table ldns_error_str[] = {
        { LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED, "RR not covered by the given NSEC RRs" },
        { LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED, "wildcard not covered by the given NSEC RRs" },
        { LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND, "original of NSEC3 hashed name could not be found" },
+       { LDNS_STATUS_MALFORMED_RRSIG, "Some of the fields of the RRSIG were missing or malformed" },
        { 0, NULL }
 };
 
index 1563e821b6df35d2547ad20a652399c19fe6336a..c9eb1731ae228a2635400a48c9c0ce89e88b1864 100644 (file)
--- a/higher.c
+++ b/higher.c
@@ -310,7 +310,12 @@ ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
         uint16_t pos = 0;
         uint16_t bit_pos;
        ldns_rdf *nsec_type_list = ldns_rr_rdf(nsec, 1); 
-       uint8_t *data = ldns_rdf_data(nsec_type_list);
+       uint8_t *data;
+       
+       if (nsec_type_list == NULL) {
+               return false;
+       }
+       data  = ldns_rdf_data(nsec_type_list);
 
        while(pos < ldns_rdf_size(nsec_type_list)) {
                window_block_nr = data[pos];
index b5b012f9a67cde3e3b114525f41ad7911f0f1d18..c9d644f9c632ded61e6b64d72518cffb4ef03c72 100644 (file)
@@ -1144,6 +1144,7 @@ ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
 {
        uint16_t i, flags;
        ldns_status status = LDNS_STATUS_OK;
+
        if (!rr) {
                ldns_buffer_printf(output, "(null)\n");
        } else {
@@ -1178,6 +1179,7 @@ ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
                }
 
                for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+                       /* ldns_rdf2buffer_str handles NULL input fine! */
                        status = ldns_rdf2buffer_str(output, ldns_rr_rdf(rr, i));
                         if(status != LDNS_STATUS_OK)
                                 return status;
@@ -1191,33 +1193,35 @@ ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
                if (ldns_rr_rd_count(rr) > 0) {
                        switch (ldns_rr_get_type(rr)) {
                                case LDNS_RR_TYPE_DNSKEY:
-                                       if (ldns_rr_rdf(rr, 0)) {
-                                               flags = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
-                                               if (flags == 256 || flags == 384) {
-                                                       ldns_buffer_printf(output,
-                                                                       " ;{id = %u (zsk), size = %db}",
-                                                                       (unsigned int) ldns_calc_keytag(rr),
-                                                                       ldns_rr_dnskey_key_size(rr));
-                                                       break;
-                                               }
-                                               if (flags == 257 || flags == 385) {
-                                                       ldns_buffer_printf(output,
-                                                                       " ;{id = %u (ksk), size = %db}",
-                                                                       (unsigned int) ldns_calc_keytag(rr),
-                                                                       ldns_rr_dnskey_key_size(rr));
-                                                       break;
-                                               }
-                                               ldns_buffer_printf(output, " ;{id = %u, size = %db}",
+                                       /* if ldns_rr_rd_count(rr) > 0
+                                          then ldns_rr_rdf(rr, 0) exists! */
+                                       flags = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
+                                       if (flags == 256 || flags == 384) {
+                                               ldns_buffer_printf(output,
+                                                               " ;{id = %u (zsk), size = %db}",
                                                                (unsigned int) ldns_calc_keytag(rr),
                                                                ldns_rr_dnskey_key_size(rr));
+                                               break;
                                        }
+                                       if (flags == 257 || flags == 385) {
+                                               ldns_buffer_printf(output,
+                                                               " ;{id = %u (ksk), size = %db}",
+                                                               (unsigned int) ldns_calc_keytag(rr),
+                                                               ldns_rr_dnskey_key_size(rr));
+                                               break;
+                                       }
+                                       ldns_buffer_printf(output, " ;{id = %u, size = %db}",
+                                                       (unsigned int) ldns_calc_keytag(rr),
+                                                       ldns_rr_dnskey_key_size(rr));
                                        break;
                                case LDNS_RR_TYPE_RRSIG:
-                                       ldns_buffer_printf(output, " ;{id = %d}",
-                                                       ldns_rdf2native_int16(ldns_rr_rdf(rr, 6)));
+                                       if (ldns_rr_rdf(rr, 6) != NULL) {
+                                               ldns_buffer_printf(output, " ;{id = %d}",
+                                                               ldns_rdf2native_int16(ldns_rr_rdf(rr, 6)));
+                                       }
                                        break;
                                case LDNS_RR_TYPE_DS:
-                                       {
+                                       if (ldns_rr_rdf(rr, 3) != NULL) {
                                                uint8_t *data = ldns_rdf_data(ldns_rr_rdf(rr, 3));
                                                size_t len = ldns_rdf_size(ldns_rr_rdf(rr, 3));
                                                char *babble = ldns_bubblebabble(data, len);
index 1ffb0f51686cdebe9d36d69770a1e600c7a59fbb..ca28dba933642297e87200b2ed156937d20e6fd7 100644 (file)
@@ -138,10 +138,11 @@ ldns_rr2buffer_wire_canonical(ldns_buffer *buffer,
 
                for (i = 0; i < ldns_rr_rd_count(rr); i++) {
                        if (pre_rfc3597) {
-                               (void) ldns_rdf2buffer_wire_canonical(buffer,
-                                                                                          ldns_rr_rdf(rr, i));
+                               (void) ldns_rdf2buffer_wire_canonical(
+                                               buffer, ldns_rr_rdf(rr, i));
                        } else {
-                               (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
+                               (void) ldns_rdf2buffer_wire(
+                                               buffer, ldns_rr_rdf(rr, i));
                        }
                }
                
@@ -178,7 +179,8 @@ ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section)
                }       
 
                for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-                       (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
+                       (void) ldns_rdf2buffer_wire(
+                                       buffer, ldns_rr_rdf(rr, i));
                }
                
                if (rdl_pos != 0) {
@@ -203,9 +205,7 @@ ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
        /* Convert all the rdfs, except the actual signature data
         * rdf number 8  - the last, hence: -1 */
        for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) {
-               if (ldns_rr_rdf(rr, i)) {
-                       (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
-               }
+               (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
        }
 
        return ldns_buffer_status(buffer);
index e17846f38b3b1bc4c0dbbd4dc02144a86f8fccd4..c25a8271763409c0dd5e15c312c392ef06c58a52 100644 (file)
@@ -98,7 +98,8 @@ enum ldns_enum_status {
        LDNS_STATUS_DNSSEC_EXISTENCE_DENIED,
        LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED,
        LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED,
-       LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND
+       LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND,
+       LDNS_STATUS_MALFORMED_RRSIG
 };
 typedef enum ldns_enum_status ldns_status;
 
diff --git a/rr.c b/rr.c
index bfdcf0bad2fd8b9869dfc32bb437795a8c96e0eb..3e24cbdee3df44c6f92de944dc94a3f20a468a1b 100644 (file)
--- a/rr.c
+++ b/rr.c
@@ -838,7 +838,7 @@ ldns_rr_pop_rdf(ldns_rr *rr)
 ldns_rdf *
 ldns_rr_rdf(const ldns_rr *rr, size_t nr)
 {
-       if (nr < ldns_rr_rd_count(rr)) {
+       if (rr && nr < ldns_rr_rd_count(rr)) {
                return rr->_rdata_fields[nr];
        } else {
                return NULL;
@@ -1638,7 +1638,10 @@ ldns_rr_compare_ds_dnskey(ldns_rr *ds,
                return false;
        }
 
-algo = ldns_rdf2native_int8(ldns_rr_rdf(ds, 2));
+       if (ldns_rr_rdf(ds, 2) == NULL) {
+               return false;
+       }
+       algo = ldns_rdf2native_int8(ldns_rr_rdf(ds, 2));
 
        ds_gen = ldns_key_rr2ds(dnskey, algo);
        if (ds_gen) {
index 700372b91c85dff0a25fbda135357ab72d7d7b53..9dca09e9e7b70b82c683b25662b81613e1bbec07 100644 (file)
@@ -331,7 +331,8 @@ ldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
 size_t 
 ldns_rr_dnskey_key_size(const ldns_rr *key) 
 {
-       if (!key) {
+       if (!key || !ldns_rr_dnskey_key(key) 
+                       || !ldns_rr_dnskey_algorithm(key)) {
                return 0;
        }
        return ldns_rr_dnskey_key_size_raw((unsigned char*)ldns_rdf_data(ldns_rr_dnskey_key(key)),
diff --git a/tsig.c b/tsig.c
index 7fcf21da0ea7fde29b825e48689e139f8ab293b2..f2fae85d46e40a9b5b6dc4b2deba77b0432576a5 100644 (file)
--- a/tsig.c
+++ b/tsig.c
@@ -288,7 +288,7 @@ ldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const ch
 
        ldns_rr *orig_tsig = ldns_pkt_tsig(pkt);
 
-       if (!orig_tsig) {
+       if (!orig_tsig || ldns_rr_rd_count(orig_tsig) <= 6) {
                ldns_rdf_deep_free(key_name_rdf);
                return false;
        }
index 01e67aa0691699a760934eeaa22e0a82a16ad000..96f72ce199bc3d6e92f4d59ff86c076f4fff4a79 100644 (file)
--- a/update.c
+++ b/update.c
@@ -113,7 +113,8 @@ ldns_update_soa_mname(ldns_rdf *zone, ldns_resolver *r,
        /* Expect a SOA answer. */
        *mname = NULL;
        while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_answer(resp)))) {
-               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA)
+               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
+                               || ldns_rr_rdf(soa_rr, 0) == NULL)
                        continue;
                /* [RFC1035 3.3.13] */
                *mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));
@@ -161,7 +162,8 @@ ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r,
 
        /* XXX Is it safe to only look in authority section here? */
        while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_authority(resp)))) {
-               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA)
+               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
+                               || ldns_rr_rdf(soa_rr, 0) == NULL)
                        continue;
                /* [RFC1035 3.3.13] */
                soa_mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));
@@ -244,7 +246,8 @@ ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r,
 
        /* XXX Is it safe to only look in authority section here, too? */
        while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_authority(resp)))) {
-               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA)
+               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
+                               || ldns_rr_rdf(soa_rr, 0) == NULL)
                        continue;
                /* [RFC1035 3.3.13] */
                soa_mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));