Open jlchristi opened 4 years ago
Thanks for the bug report. At first glance this appears to be a bug in our response parsing logic.
@addaleax @XadillaX Maybe not the root cause but those bounds checks look like UB to me.
Pointers in C and C++ are allowed to point one element past the end of an array and no more. The check should look like this:
diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc
index 73a0ac6b33..778e0821d7 100644
--- a/src/cares_wrap.cc
+++ b/src/cares_wrap.cc
@@ -1075,7 +1075,7 @@ int ParseSoaReply(Environment* env,
return status == ARES_EBADNAME ? ARES_EBADRESP : status;
}
- if (ptr + temp_len + NS_QFIXEDSZ > buf + len) {
+ if (temp_len > LONG_MAX - NS_QFIXEDSZ || temp_len + NS_QFIXEDSZ > len) {
return ARES_EBADRESP;
}
ptr += temp_len + NS_QFIXEDSZ;
@bnoordhuis I'd like to work on this.
@bnoordhuis -
I tried tracing down function calls and I don't think the problem exists in parseSoaReply
. Instead, the Parse
function of QuerySoaWrap
is invoked.
This Parse
function handles the parsing when the ares_query
invokes its callback with a success status.
In the case when SOA response doesn't exist, the ares_query
function invokes the callback with a success status instead of ENODATA.
At this point, I think the problem exists in the ares_query
library function itself.
Also while working on this, I discovered a bug related to free call on garbage pointer. #35502
v20.11.0 the bug is still there
What steps will reproduce the bug?
Actual Results
hostname: support.microsoft.com CNAME result: [ 'ev.support.microsoft.com.edgekey.net' ] SOA result: querySoa EBADRESP support.microsoft.com
Expected Results
hostname: support.microsoft.com CNAME result: [ 'ev.support.microsoft.com.edgekey.net' ] SOA result: querySoa ENODATA support.microsoft.com
Additional information
This seems to happen for any hostname with a CNAME record.
Another example:
hostname: store.gocomics.com CNAME result: [ 'gocomicsstore.wpengine.com' ] SOA result: querySoa EBADRESP store.gocomics.com
I would expect to get an 'ENODATA' instead of 'EBADRESP', as with the other resolveXXX() calls.
For a hostname with an SOA record but no CNAME, you get:
hostname: microsoft.com CNAME result: queryCname ENODATA microsoft.com SOA result: {"nsname":"ns1-205.azure-dns.com","hostmaster":"azuredns- hostmaster.microsoft.com","serial":1,"refresh":3600,"retry":300,"expire":2419200,"minttl":300}