diff options
author | Paul Dreik <github@pauldreik.se> | 2019-09-14 03:16:09 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2019-09-15 23:25:24 +0200 |
commit | b7666027296a4f89a8ce6b22af335e8aee7a7782 (patch) | |
tree | e75c54442cdb8ed02be13d2a8d4dd7de16f90e2b /lib | |
parent | 5eb75d418657a734bfbe02e5aef69cc5fe28ebc6 (diff) |
doh: fix (harmless) buffer overrun
Added unit test case 1655 to verify.
Close #4352
the code correctly finds the flaws in the old code,
if one temporarily restores doh.c to the old version.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/doh.c | 17 |
1 files changed, 15 insertions, 2 deletions
@@ -74,17 +74,26 @@ static const char *doh_strerror(DOHcode code) #define UNITTEST static #endif +/* @unittest 1655 + */ UNITTEST DOHcode doh_encode(const char *host, DNStype dnstype, unsigned char *dnsp, /* buffer */ size_t len, /* buffer size */ size_t *olen) /* output length */ { - size_t hostlen = strlen(host); + const size_t hostlen = strlen(host); unsigned char *orig = dnsp; const char *hostp = host; - if(len < (12 + hostlen + 4)) + /* The expected output length does not depend on the number of dots within + * the host name. It will always be two more than the length of the host + * name, one for the size and one trailing null. In case there are dots, + * each dot adds one size but removes the need to store the dot, net zero. + */ + const size_t expected_len = 12 + ( 1 + hostlen + 1) + 4; + + if(len < expected_len) return DOH_TOO_SMALL_BUFFER; *dnsp++ = 0; /* 16 bit id */ @@ -132,6 +141,10 @@ UNITTEST DOHcode doh_encode(const char *host, *dnsp++ = DNS_CLASS_IN; /* IN - "the Internet" */ *olen = dnsp - orig; + + /* verify that our assumption of length is valid, since + * this has lead to buffer overflows in this function */ + DEBUGASSERT(*olen == expected_len); return DOH_OK; } |