Blank DNS names would result in ARES_ENOMEM due to bug in query cache

If a blank DNS name is used, the DNS query cache would fail due to an
invalid sanity check.  This can be legitimate such as:

adig -t SOA .

This fixes that situation as well as a few other spots that were
uncovered and adds a test case to validate the behavior to ensure
it won't regress in the future.

Fixes #858
Reported-By: Nodar Chkuaselidze (@nodech)
Authored-By: Brad House (@bradh352)
pull/863/head
Brad House 3 months ago
parent 5b70955d51
commit 083d6c9c0f
  1. 8
      src/lib/ares_qcache.c
  2. 6
      src/lib/ares_send.c
  3. 6
      src/lib/str/ares__buf.c
  4. 2
      test/ares-test-internal.cc
  5. 22
      test/ares-test-mock.cc

@ -121,9 +121,11 @@ static char *ares__qcache_calc_key(const ares_dns_record_t *dnsrec)
name_len--;
}
status = ares__buf_append(buf, (const unsigned char *)name, name_len);
if (status != ARES_SUCCESS) {
goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
if (name_len > 0) {
status = ares__buf_append(buf, (const unsigned char *)name, name_len);
if (status != ARES_SUCCESS) {
goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
}
}
}

@ -62,7 +62,11 @@ static ares_status_t ares_apply_dns0x20(ares_channel_t *channel,
}
len = ares_strlen(name);
if (len == 0 || len >= sizeof(dns0x20name)) {
if (len == 0) {
return ARES_SUCCESS;
}
if (len >= sizeof(dns0x20name)) {
status = ARES_EBADNAME;
goto done;
}

@ -213,10 +213,14 @@ ares_status_t ares__buf_append(ares__buf_t *buf, const unsigned char *data,
{
ares_status_t status;
if (data == NULL || data_len == 0) {
if (data == NULL && data_len != 0) {
return ARES_EFORMERR;
}
if (data_len == 0) {
return ARES_SUCCESS;
}
status = ares__buf_ensure_space(buf, data_len);
if (status != ARES_SUCCESS) {
return status;

@ -1021,7 +1021,7 @@ TEST_F(LibraryTest, ArrayMisuse) {
TEST_F(LibraryTest, BufMisuse) {
EXPECT_EQ(NULL, ares__buf_create_const(NULL, 0));
ares__buf_reclaim(NULL);
EXPECT_NE(ARES_SUCCESS, ares__buf_append(NULL, NULL, 0));
EXPECT_NE(ARES_SUCCESS, ares__buf_append(NULL, NULL, 55));
size_t len = 10;
EXPECT_EQ(NULL, ares__buf_append_start(NULL, &len));
EXPECT_EQ(NULL, ares__buf_append_start(NULL, NULL));

@ -817,6 +817,28 @@ TEST_P(MockChannelTest, SearchDomains) {
EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
}
// Issue #858
TEST_P(CacheQueriesTest, BlankName) {
DNSPacket rsp;
rsp.set_response().set_aa()
.add_question(new DNSQuestion(".", T_SOA))
.add_answer(new DNSSoaRR(".", 600, "a.root-servers.net", "nstld.verisign-grs.com", 123456, 3600, 3600, 3600, 3600));
EXPECT_CALL(server_, OnRequest("", T_SOA))
.WillOnce(SetReply(&server_, &rsp));
QueryResult result;
ares_query_dnsrec(channel_, ".", ARES_CLASS_IN, ARES_REC_TYPE_SOA, QueryCallback, &result, NULL);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(0, result.timeouts_);
QueryResult cacheresult;
ares_query_dnsrec(channel_, ".", ARES_CLASS_IN, ARES_REC_TYPE_SOA, QueryCallback, &cacheresult, NULL);
Process();
EXPECT_TRUE(cacheresult.done_);
EXPECT_EQ(0, cacheresult.timeouts_);
}
TEST_P(CacheQueriesTest, SearchDomainsCache) {
DNSPacket nofirst;
nofirst.set_response().set_aa().set_rcode(NXDOMAIN)

Loading…
Cancel
Save