diff --git a/doc/Changelog b/doc/Changelog index 46ad6ec7d..4ecb5ffbf 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/services/outside_network.c b/services/outside_network.c index c5d6782b3..9b1490e64 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -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);