]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #503: DNS over HTTPS response truncated.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 Jun 2021 12:05:59 +0000 (14:05 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 Jun 2021 12:05:59 +0000 (14:05 +0200)
doc/Changelog
services/listen_dnsport.c
sldns/parseutil.c
sldns/parseutil.h

index 6456672960de56540b0c3c8423cfe92965bd8903..9ac461e5aaaee140eee3ba4711b99b094d12336e 100644 (file)
@@ -1,3 +1,6 @@
+23 June 2021: Wouter
+       - Fix #503: DNS over HTTPS response truncated.
+
 21 June 2021: George
        - Fix #495: Documentation or implementation of "verbosity" option.
 
index ca40fac5cc67cf40189ed127ed7f0aa74fef1097..52b0a2ee9aa3058c42fa0bf7b55854d26140e1c6 100644 (file)
@@ -2678,18 +2678,45 @@ static int http2_buffer_uri_query(struct http2_session* h2_session,
                return 0;
        }
 
-       if(!(b64len = sldns_b64url_pton(
-               (char const *)start, length,
-               sldns_buffer_current(h2_stream->qbuffer),
-               expectb64len)) || b64len < 0) {
-               lock_basic_lock(&http2_query_buffer_count_lock);
-               http2_query_buffer_count -= expectb64len;
-               lock_basic_unlock(&http2_query_buffer_count_lock);
-               sldns_buffer_free(h2_stream->qbuffer);
-               h2_stream->qbuffer = NULL;
-               /* return without error, method can be an
-                * unknown POST */
-               return 1;
+       if(sldns_b64_contains_nonurl((char const*)start, length)) {
+               char buf[65536+4];
+               verbose(VERB_ALGO, "HTTP2 stream contains wrong b64 encoding");
+               /* copy to the scratch buffer temporarily to terminate the
+                * string with a zero */
+               if(length+1 > sizeof(buf)) {
+                       /* too long */
+                       lock_basic_lock(&http2_query_buffer_count_lock);
+                       http2_query_buffer_count -= expectb64len;
+                       lock_basic_unlock(&http2_query_buffer_count_lock);
+                       sldns_buffer_free(h2_stream->qbuffer);
+                       h2_stream->qbuffer = NULL;
+                       return 1;
+               }
+               memmove(buf, start, length);
+               buf[length] = 0;
+               if(!(b64len = sldns_b64_pton(buf, sldns_buffer_current(
+                       h2_stream->qbuffer), expectb64len)) || b64len < 0) {
+                       lock_basic_lock(&http2_query_buffer_count_lock);
+                       http2_query_buffer_count -= expectb64len;
+                       lock_basic_unlock(&http2_query_buffer_count_lock);
+                       sldns_buffer_free(h2_stream->qbuffer);
+                       h2_stream->qbuffer = NULL;
+                       return 1;
+               }
+       } else {
+               if(!(b64len = sldns_b64url_pton(
+                       (char const *)start, length,
+                       sldns_buffer_current(h2_stream->qbuffer),
+                       expectb64len)) || b64len < 0) {
+                       lock_basic_lock(&http2_query_buffer_count_lock);
+                       http2_query_buffer_count -= expectb64len;
+                       lock_basic_unlock(&http2_query_buffer_count_lock);
+                       sldns_buffer_free(h2_stream->qbuffer);
+                       h2_stream->qbuffer = NULL;
+                       /* return without error, method can be an
+                        * unknown POST */
+                       return 1;
+               }
        }
        sldns_buffer_skip(h2_stream->qbuffer, (size_t)b64len);
        return 1;
index 9f289d3596c39114cbd481efbb887d2fe3811288..ba71df55d501d0d7483af45573eb7546d45f0d84 100644 (file)
@@ -790,3 +790,18 @@ int sldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
        }
        return sldns_b64_pton_base(src, srcsize, target, targsize, 1);
 }
+
+int sldns_b64_contains_nonurl(char const *src, size_t srcsize)
+{
+       const char* s = src;
+       while(*s && srcsize) {
+               char d = *s++;
+               srcsize--;
+               /* the '+' and the '/' and padding '=' is not allowed in b64
+                * url encoding */
+               if(d == '+' || d == '/' || d == '=') {
+                       return 1;
+               }
+       }
+       return 0;
+}
index 7eb23317f285dcb4dd61ac1371f2c45461b60d0c..74d7c727571aa6a5c13659d97a983fcdd8420c6c 100644 (file)
@@ -102,6 +102,7 @@ size_t sldns_b64_pton_calculate_size(size_t srcsize);
 int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
 int sldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
        size_t targsize);
+int sldns_b64_contains_nonurl(char const *src, size_t srcsize);
 
 /**
  * calculates the size needed to store the result of b32_ntop