]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix assertion for low buffer size and big edns payload when worker
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 29 May 2017 07:32:45 +0000 (07:32 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 29 May 2017 07:32:45 +0000 (07:32 +0000)
  overrides udpsize.

git-svn-id: file:///svn/unbound/trunk@4195 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/worker.c
doc/Changelog
util/data/msgencode.c

index efe97d6d683a1c14ae796f397a44ac907662d04c..2c4cf5ba6c0a18beb5791bfac9217e6204d6b69c 100644 (file)
@@ -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;
        }
index e27214c651cf6ae9c3ec211fa20a326c1d68b047..c08f4b5db793e3b0868496ea929555b645720299 100644 (file)
@@ -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.
 
index 1f72a03b8c64d92dcd4dbab313497f0662714eba..259df3693a5ebf5b19f378fdfaa07f1a81191837 100644 (file)
@@ -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;
 }