From: Wouter Wijngaards Date: Tue, 1 May 2007 15:11:53 +0000 (+0000) Subject: Documentation addresses and check buffer limit. X-Git-Tag: release-0.3~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=182855d233a20a5be6586439b5a5974de57c1aa7;p=thirdparty%2Funbound.git Documentation addresses and check buffer limit. git-svn-id: file:///svn/unbound/trunk@273 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 43386e3c4..ccc43e452 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -3,6 +3,9 @@ But only for answers from other servers, not for plain queries. - compression and decompression test cases. - some stats added. + - example.conf interface: line is changed from 127.0.0.1 which leads + to problems if used (restricting communication to the localhost), + to a documentation and test address. 27 April 2007: Wouter - removed iov usage, it is not good for dns message encoding. diff --git a/doc/example.conf b/doc/example.conf index c1c7091b1..10e71087c 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -20,7 +20,10 @@ server: # specify the interfaces to answer queries from by ip-address. # If you give none the default (all) interface is used. - # interface: 192.168.0.153 + # specify every interface on a new 'interface:' labelled line. + # interface: 192.0.2.153 + # interface: 192.0.2.154 + # interface: 2001:DB8::5 # port to answer queries from # port: 53 diff --git a/util/data/dname.c b/util/data/dname.c index 77848e290..3d1ca464e 100644 --- a/util/data/dname.c +++ b/util/data/dname.c @@ -452,17 +452,22 @@ dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs) return lastdiff; } -void +int dname_buffer_write(ldns_buffer* pkt, uint8_t* dname) { uint8_t lablen; + if(ldns_buffer_remaining(pkt) < 1) + return 0; lablen = *dname++; ldns_buffer_write_u8(pkt, lablen); while(lablen) { + if(ldns_buffer_remaining(pkt) < (size_t)lablen+1) + return 0; ldns_buffer_write(pkt, dname, lablen); dname += lablen; lablen = *dname++; ldns_buffer_write_u8(pkt, lablen); } + return 1; } diff --git a/util/data/dname.h b/util/data/dname.h index d0e5f86fd..b10b66f1c 100644 --- a/util/data/dname.h +++ b/util/data/dname.h @@ -123,8 +123,9 @@ void dname_pkt_copy(ldns_buffer* pkt, uint8_t* to, uint8_t* dname); * Copy over a valid dname to a packet. * @param pkt: packet to copy to. * @param dname: dname to copy. + * @return: 0 if not enough space in buffer. */ -void dname_buffer_write(ldns_buffer* pkt, uint8_t* dname); +int dname_buffer_write(ldns_buffer* pkt, uint8_t* dname); /** debug helper. Print wireformat dname to output. * @param out: like stdout or a file. diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 1f0aaf0b7..31b2efc38 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -705,12 +705,17 @@ compress_owner(struct ub_packed_rrset_key* key, ldns_buffer* pkt, * not capable of decoding ptr after a ptr. */ *owner_ptr = htons((uint16_t)(0xc000 | p->offset)); + /* check if ptr + tc+4 ttl + rdatalen is available */ + if(ldns_buffer_remaining(pkt) < 2+4+4+2) + return 0; write_compressed_dname(pkt, key->rk.dname, owner_labs, p); ldns_buffer_write(pkt, &key->rk.dname[ key->rk.dname_len], 4); } else { /* no compress */ + if(ldns_buffer_remaining(pkt) < key->rk.dname_len+4+4+2) + return 0; ldns_buffer_write(pkt, key->rk.dname, key->rk.dname_len+4); if(owner_pos <= PTR_MAX_OFFSET) @@ -722,6 +727,8 @@ compress_owner(struct ub_packed_rrset_key* key, ldns_buffer* pkt, return 0; } else { /* always compress 2nd-further RRs in RRset */ + if(ldns_buffer_remaining(pkt) < 2+4+4+2) + return 0; ldns_buffer_write(pkt, owner_ptr, 2); ldns_buffer_write(pkt, &key->rk.dname[key->rk.dname_len], 4); } @@ -736,6 +743,8 @@ compress_any_dname(uint8_t* dname, ldns_buffer* pkt, int labs, struct compress_tree_node* p; size_t pos = ldns_buffer_position(pkt); if((p = compress_tree_lookup(*tree, dname, labs))) { + if(ldns_buffer_remaining(pkt) < 2) + return 0; write_compressed_dname(pkt, dname, labs, p); } else { dname_buffer_write(pkt, dname); @@ -767,6 +776,7 @@ compress_rdata(ldns_buffer* pkt, uint8_t* rdata, size_t todolen, uint8_t count = desc->_dname_count; ldns_buffer_skip(pkt, 2); /* rdata len fill in later */ + /* space for rdatalen checked for already */ rdata += 2; todolen -= 2; while(todolen > 0 && count) { @@ -788,6 +798,8 @@ compress_rdata(ldns_buffer* pkt, uint8_t* rdata, size_t todolen, } if(len) { /* copy over */ + if(ldns_buffer_remaining(pkt) < len) + return 0; ldns_buffer_write(pkt, rdata, len); todolen -= len; rdata += len; @@ -796,6 +808,8 @@ compress_rdata(ldns_buffer* pkt, uint8_t* rdata, size_t todolen, } /* copy remainder */ if(todolen > 0) { + if(ldns_buffer_remaining(pkt) < todolen) + return 0; ldns_buffer_write(pkt, rdata, todolen); } @@ -829,6 +843,8 @@ packed_rrset_iov(struct ub_packed_rrset_key* key, ldns_buffer* pkt, return 0; } else { /* no compression */ + if(ldns_buffer_remaining(pkt) < + key->rk.dname_len + 4+4+2) return 0; ldns_buffer_write(pkt, key->rk.dname, key->rk.dname_len + 4); } @@ -837,8 +853,12 @@ packed_rrset_iov(struct ub_packed_rrset_key* key, ldns_buffer* pkt, if(!compress_rdata(pkt, data->rr_data[i], data->rr_len[i], region, tree, c)) return 0; - } else ldns_buffer_write(pkt, data->rr_data[i], - data->rr_len[i]); + } else { + if(ldns_buffer_remaining(pkt) < data->rr_len[i]) + return 0; + ldns_buffer_write(pkt, data->rr_data[i], + data->rr_len[i]); + } } } /* insert rrsigs */ @@ -847,15 +867,21 @@ packed_rrset_iov(struct ub_packed_rrset_key* key, ldns_buffer* pkt, *num_rrs += data->rrsig_count; for(i=data->count; irr_len[i]) + return 0; ldns_buffer_write(pkt, &owner_ptr, 2); - else { + } else { if(!compress_any_dname(key->rk.dname, pkt, owner_labs, region, tree)) return 0; } } else { /* no compression */ + if(ldns_buffer_remaining(pkt) < + key->rk.dname_len+4+4+data->rr_len[i]) + return 0; ldns_buffer_write(pkt, key->rk.dname, key->rk.dname_len); } @@ -885,8 +911,10 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs, for(i=0; irrsets[rrsets_before+i], pkt, num_rrs, timenow, region, 1, 1, tree)) + /* Bad, but if due to size must set TC bit */ return 0; } else { + /* might be OKAY to discard rrsets at end */ for(i=0; irrsets[rrsets_before+i], pkt, num_rrs, timenow, region, 1, 0, tree)) @@ -907,7 +935,7 @@ int reply_info_encode(struct query_info* qinfo, struct reply_info* rep, struct compress_tree_node* tree = 0; ldns_buffer_clear(buffer); - if(ldns_buffer_capacity(buffer) < LDNS_HEADER_SIZE) + if(ldns_buffer_remaining(buffer) < LDNS_HEADER_SIZE) return 0; ldns_buffer_write(buffer, &id, sizeof(uint16_t));