]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- More fixes in depth for buffer checks in 0x20 qname checks.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 13 Jun 2017 14:34:44 +0000 (14:34 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 13 Jun 2017 14:34:44 +0000 (14:34 +0000)
git-svn-id: file:///svn/unbound/trunk@4225 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
services/outside_network.c

index 46ad6ec7d8073dcbe99475fc4c4437775e63c385..4ecb5ffbf9aae0162ea32071cc3d739ea49dc2c4 100644 (file)
@@ -4,6 +4,7 @@
          contains malformed qname.  When 0x20 caps-for-id is enabled, when
          assertions are not enabled the malformed qname is handled correctly.
        - 1.6.3 tag created, with only #1280 fix, trunk is 1.6.4 development.
+       - More fixes in depth for buffer checks in 0x20 qname checks.
 
 12 June 2017: Wouter
        - Fix #1278: Incomplete wildcard proof.
index c5d6782b3108bb9ec78f882e35e70c7a6012722e..9b1490e643f848711e58c01f02c48d161937e786 100644 (file)
@@ -1548,18 +1548,22 @@ serviced_udp_send(struct serviced_query* sq, sldns_buffer* buff)
 static int
 serviced_check_qname(sldns_buffer* pkt, uint8_t* qbuf, size_t qbuflen)
 {
-       uint8_t* d1 = sldns_buffer_at(pkt, 12);
+       uint8_t* d1 = sldns_buffer_begin(pkt)+12;
        uint8_t* d2 = qbuf+10;
        uint8_t len1, len2;
        int count = 0;
+       if(sldns_buffer_limit(pkt) < 12+1+4) /* packet too small for qname */
+               return 0;
        log_assert(qbuflen >= 15 /* 10 header, root, type, class */);
        len1 = *d1++;
        len2 = *d2++;
-       if(sldns_buffer_limit(pkt) < 12+1+4) /* packet too small for qname */
-               return 0;
        while(len1 != 0 || len2 != 0) {
                if(LABEL_IS_PTR(len1)) {
+                       /* check if we can read *d1 with compression ptr rest */
+                       if(d1 >= sldns_buffer_at(pkt, sldns_buffer_limit(pkt)))
+                               return 0;
                        d1 = sldns_buffer_begin(pkt)+PTR_OFFSET(len1, *d1);
+                       /* check if we can read the destination *d1 */
                        if(d1 >= sldns_buffer_at(pkt, sldns_buffer_limit(pkt)))
                                return 0;
                        len1 = *d1++;
@@ -1573,6 +1577,9 @@ serviced_check_qname(sldns_buffer* pkt, uint8_t* qbuf, size_t qbuflen)
                        return 0;
                if(len1 > LDNS_MAX_LABELLEN)
                        return 0;
+               /* check len1 + 1(next length) are okay to read */
+               if(d1+len1 >= sldns_buffer_at(pkt, sldns_buffer_limit(pkt)))
+                       return 0;
                log_assert(len1 <= LDNS_MAX_LABELLEN);
                log_assert(len2 <= LDNS_MAX_LABELLEN);
                log_assert(len1 == len2 && len1 != 0);