From: Wouter Wijngaards Date: Mon, 29 May 2017 07:32:45 +0000 (+0000) Subject: - Fix assertion for low buffer size and big edns payload when worker X-Git-Tag: release-1.6.4rc1~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8b2397542e4cedd8c3f906b3b69cde964c66d9f7;p=thirdparty%2Funbound.git - Fix assertion for low buffer size and big edns payload when worker overrides udpsize. git-svn-id: file:///svn/unbound/trunk@4195 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/daemon/worker.c b/daemon/worker.c index efe97d6d6..2c4cf5ba6 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -811,7 +811,9 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns, if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL, LDNS_RCODE_NOERROR, edns, worker->scratchpad)) edns->opt_list = NULL; - attach_edns_record(pkt, edns); + if(sldns_buffer_capacity(pkt) >= + sldns_buffer_limit(pkt)+calc_edns_field_size(edns)) + attach_edns_record(pkt, edns); } /** Reply with one string */ @@ -1187,7 +1189,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error, error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer), sldns_buffer_read_u16_at(c->buffer, 2), NULL); - attach_edns_record(c->buffer, &edns); + if(sldns_buffer_capacity(c->buffer) >= + sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns)) + attach_edns_record(c->buffer, &edns); regional_free_all(worker->scratchpad); goto send_reply; } diff --git a/doc/Changelog b/doc/Changelog index e27214c65..c08f4b5db 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +29 May 2017: Wouter + - Fix assertion for low buffer size and big edns payload when worker + overrides udpsize. + 26 May 2017: Ralph - Added redirect-bogus.patch to contrib directory. diff --git a/util/data/msgencode.c b/util/data/msgencode.c index 1f72a03b8..259df3693 100644 --- a/util/data/msgencode.c +++ b/util/data/msgencode.c @@ -647,6 +647,8 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, sldns_buffer_clear(buffer); if(udpsize < sldns_buffer_limit(buffer)) sldns_buffer_set_limit(buffer, udpsize); + else if(sldns_buffer_limit(buffer) < udpsize) + udpsize = sldns_buffer_limit(buffer); if(sldns_buffer_remaining(buffer) < LDNS_HEADER_SIZE) return 0; @@ -810,7 +812,7 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, struct edns_data* edns, int dnssec, int secure) { uint16_t flags; - int attach_edns = 1; + unsigned int attach_edns = 0; if(!cached || rep->authoritative) { /* original flags, copy RD and CD bits from query. */ @@ -833,12 +835,15 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, log_assert(flags & BIT_QR); /* QR bit must be on in our replies */ if(udpsize < LDNS_HEADER_SIZE) return 0; + if(sldns_buffer_capacity(pkt) < udpsize) + udpsize = sldns_buffer_capacity(pkt); if(udpsize < LDNS_HEADER_SIZE + calc_edns_field_size(edns)) { /* packet too small to contain edns, omit it. */ attach_edns = 0; } else { /* reserve space for edns record */ - udpsize -= calc_edns_field_size(edns); + attach_edns = (int)calc_edns_field_size(edns); + udpsize -= attach_edns; } if(!reply_info_encode(qinf, rep, id, flags, pkt, timenow, region, @@ -846,7 +851,8 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, log_err("reply encode: out of memory"); return 0; } - if(attach_edns) + if(attach_edns && sldns_buffer_capacity(pkt) >= + sldns_buffer_limit(pkt)+attach_edns) attach_edns_record(pkt, edns); return 1; }