diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2020-10-21 18:05:53 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-10-21 18:05:53 +0000 |
commit | 19d9dd4a04e12a9b19019ed5668f560733907b82 (patch) | |
tree | 19b5d316488e0ef31bc7a293f0b66929094bbe97 | |
parent | a4a25fe8abc7cd8cd3bfe213b4b867a4fa194385 (diff) | |
parent | ac72fc56126dbc1d65592325ef21080bdf487524 (diff) | |
download | netd-android10-android13-mainline-tzdata-release.tar.gz |
Snap for 6921388 from ac72fc56126dbc1d65592325ef21080bdf487524 to qt-aml-tzdata-releaseq_tzdata_aml_297100400q_tzdata_aml_297100300q_tzdata_aml_297100000q_tzdata_aml_296200000q_tzdata_aml_295600118q_tzdata_aml_295600110q_tzdata_aml_295500002q_tzdata_aml_295500001q_tzdata_aml_294400310android-mainline-12.0.0_r54android-mainline-12.0.0_r111android-mainline-10.0.0_r13android-mainline-10.0.0_r12q_tzdata_aml_297100000android12-mainline-tzdata-releaseandroid10-mainline-tzdata-releaseandroid10-android13-mainline-tzdata-release
Change-Id: I29eaa5c8c59e2b7b5cdc35e2d5d1b4adeadc64c3
-rw-r--r-- | resolv/libnetd_resolv_test.cpp | 140 | ||||
-rw-r--r-- | resolv/res_cache.cpp | 9 | ||||
-rw-r--r-- | resolv/res_send.cpp | 5 | ||||
-rw-r--r-- | server/AndroidTest.xml | 1 |
4 files changed, 148 insertions, 7 deletions
diff --git a/resolv/libnetd_resolv_test.cpp b/resolv/libnetd_resolv_test.cpp index 6e4b9eec..f961e790 100644 --- a/resolv/libnetd_resolv_test.cpp +++ b/resolv/libnetd_resolv_test.cpp @@ -19,18 +19,24 @@ #include <gtest/gtest.h> #include <android-base/stringprintf.h> +#include <android/multinetwork.h> // ResNsendFlags #include <arpa/inet.h> +#include <arpa/nameser.h> #include <netdb.h> +#include <resolv.h> #include "dns_responder.h" #include "getaddrinfo.h" #include "gethnamaddr.h" +#include "res_send.h" #include "resolv_cache.h" #include "stats.pb.h" // TODO: make this dynamic and stop depending on implementation details. constexpr unsigned int TEST_NETID = 30; +constexpr int MAXPACKET = (8 * 1024); + // Specifying 0 in ai_socktype or ai_protocol of struct addrinfo indicates that any type or // protocol can be returned by getaddrinfo(). constexpr unsigned int ANY = 0; @@ -473,6 +479,140 @@ TEST_F(GetAddrInfoForNetContextTest, ServerTimeout) { if (result) freeaddrinfo(result); } +namespace { + +std::string toString(uint8_t* buf, int bufLen, int ipType) { + ns_msg handle; + int ancount, n = 0; + ns_rr rr; + + if (ns_initparse((const uint8_t*)buf, bufLen, &handle) >= 0) { + ancount = ns_msg_count(handle, ns_s_an); + if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) { + const uint8_t* rdata = ns_rr_rdata(rr); + char buffer[INET6_ADDRSTRLEN]; + if (inet_ntop(ipType, (const char*)rdata, buffer, sizeof(buffer))) { + return buffer; + } + } + } + return ""; +} + +std::string resolvResNsendHelper(const android_net_context* _Nonnull netContext, const char* host, + int nsType, int flag) { + std::vector<uint8_t> ansBuf(MAXPACKET, 0); + int rcode = ns_r_noerror; + std::vector<uint8_t> msg(MAXPACKET, 0); + const int msgLen = res_mkquery(ns_o_query, host, ns_c_in, nsType, nullptr, 0, nullptr, + msg.data(), MAXPACKET); + NetworkDnsEventReported event; + const int nsendAns = resolv_res_nsend(netContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET, + &rcode, static_cast<ResNsendFlags>(flag), &event); + return toString(ansBuf.data(), nsendAns, (nsType == ns_t_a) ? AF_INET : AF_INET6); +} + +} // namespace + +TEST_F(GetAddrInfoForNetContextTest, Async_CacheFlags) { + constexpr char listen_addr[] = "127.0.0.3"; + constexpr char listen_srv[] = "53"; + constexpr char host1[] = "howdy.example.com."; + constexpr char host2[] = "howdy.example2.com."; + constexpr char host3[] = "howdy.example3.com."; + test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail); + dns.addMapping(host1, ns_type::ns_t_a, "1.2.3.4"); + dns.addMapping(host3, ns_type::ns_t_a, "1.2.3.6"); + dns.addMapping(host2, ns_type::ns_t_aaaa, "::1.2.3.5"); + dns.addMapping(host3, ns_type::ns_t_aaaa, "::1.2.3.6"); + ASSERT_TRUE(dns.startServer()); + const char* servers[] = {listen_addr}; + ASSERT_EQ(0, resolv_set_nameservers_for_net(TEST_NETID, servers, + sizeof(servers) / sizeof(servers[0]), + mDefaultSearchDomains, &mDefaultParams_Binder)); + + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host1, ns_t_a, ANDROID_RESOLV_NO_CACHE_STORE), + "1.2.3.4"); + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host1, ns_t_a, ANDROID_RESOLV_NO_CACHE_STORE), + "1.2.3.4"); + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host1, ns_t_a, ANDROID_RESOLV_NO_CACHE_STORE), + "1.2.3.4"); + + // No cache exists, expect 3 queries + EXPECT_EQ(3U, GetNumQueries(dns, host1)); // no query because of the cache + + // Raise a query with no flags to ensure no cache exists. Also make an cache entry for the + // query. + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host1, ns_t_a, 0), "1.2.3.4"); + + // Expect 4 queries because there should be no cache before this query. + EXPECT_EQ(4U, GetNumQueries(dns, host1)); + + // Now we have the cache entry, re-query with ANDROID_RESOLV_NO_CACHE_STORE to ensure + // that ANDROID_RESOLV_NO_CACHE_STORE implied ANDROID_RESOLV_NO_CACHE_LOOKUP. + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host1, ns_t_a, ANDROID_RESOLV_NO_CACHE_STORE), + "1.2.3.4"); + + // Expect 5 queries because we shouldn't do cache lookup for the query which has + // ANDROID_RESOLV_NO_CACHE_STORE. + EXPECT_EQ(5U, GetNumQueries(dns, host1)); + + // ANDROID_RESOLV_NO_CACHE_LOOKUP + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host1, ns_t_a, ANDROID_RESOLV_NO_CACHE_LOOKUP), + "1.2.3.4"); + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host1, ns_t_a, ANDROID_RESOLV_NO_CACHE_LOOKUP), + "1.2.3.4"); + + // Cache was skipped, expect 2 more queries. + EXPECT_EQ(7U, GetNumQueries(dns, host1)); + + // Re-query verify cache works + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host1, ns_t_a, 0), "1.2.3.4"); + + // Cache hits, expect still 7 queries + EXPECT_EQ(7U, GetNumQueries(dns, host1)); + + // Start to verify if ANDROID_RESOLV_NO_CACHE_LOOKUP does write response into cache + dns.clearQueries(); + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host2, ns_t_aaaa, ANDROID_RESOLV_NO_CACHE_LOOKUP), + "::1.2.3.5"); + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host2, ns_t_aaaa, ANDROID_RESOLV_NO_CACHE_LOOKUP), + "::1.2.3.5"); + + // Skip cache, expect 2 queries + EXPECT_EQ(2U, GetNumQueries(dns, host2)); + + // Re-query without flags + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host2, ns_t_aaaa, 0), "::1.2.3.5"); + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host2, ns_t_aaaa, 0), "::1.2.3.5"); + + // Cache hits, expect still 2 queries + EXPECT_EQ(2U, GetNumQueries(dns, host2)); + + // Test both ANDROID_RESOLV_NO_CACHE_STORE and ANDROID_RESOLV_NO_CACHE_LOOKUP are set + dns.clearQueries(); + + // Make sure that the cache of "howdy.example3.com" exists. + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host3, ns_t_aaaa, 0), "::1.2.3.6"); + EXPECT_EQ(1U, GetNumQueries(dns, host3)); + + // Re-query with testFlags + const int testFlag = ANDROID_RESOLV_NO_CACHE_STORE | ANDROID_RESOLV_NO_CACHE_LOOKUP; + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host3, ns_t_aaaa, testFlag), "::1.2.3.6"); + // Expect cache lookup is skipped. + EXPECT_EQ(2U, GetNumQueries(dns, host3)); + + // Do another query with testFlags + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host3, ns_t_a, testFlag), "1.2.3.6"); + // Expect cache lookup is skipped. + EXPECT_EQ(3U, GetNumQueries(dns, host3)); + + // Re-query with no flags + EXPECT_EQ(resolvResNsendHelper(&mNetcontext, host3, ns_t_a, testFlag), "1.2.3.6"); + // Expect no cache hit because cache storing is also skipped in previous query. + EXPECT_EQ(4U, GetNumQueries(dns, host3)); +} + TEST_F(GetHostByNameForNetContextTest, AlphabeticalHostname) { constexpr char listen_addr[] = "127.0.0.3"; constexpr char listen_srv[] = "53"; diff --git a/resolv/res_cache.cpp b/resolv/res_cache.cpp index d6f0cd80..879ddbb4 100644 --- a/resolv/res_cache.cpp +++ b/resolv/res_cache.cpp @@ -1423,7 +1423,9 @@ ResolvCacheStatus _resolv_cache_lookup(unsigned netid, const void* query, int qu // possible to cache the answer of this query. // If ANDROID_RESOLV_NO_CACHE_STORE is set, return RESOLV_CACHE_SKIP to skip possible cache // storing. - if (flags & ANDROID_RESOLV_NO_CACHE_LOOKUP) { + // (b/150371903): ANDROID_RESOLV_NO_CACHE_STORE should imply ANDROID_RESOLV_NO_CACHE_LOOKUP + // to avoid side channel attack. + if (flags & (ANDROID_RESOLV_NO_CACHE_LOOKUP | ANDROID_RESOLV_NO_CACHE_STORE)) { return flags & ANDROID_RESOLV_NO_CACHE_STORE ? RESOLV_CACHE_SKIP : RESOLV_CACHE_NOTFOUND; } Entry key; @@ -1456,11 +1458,6 @@ ResolvCacheStatus _resolv_cache_lookup(unsigned netid, const void* query, int qu if (e == NULL) { LOG(INFO) << __func__ << ": NOT IN CACHE"; - // If it is no-cache-store mode, we won't wait for possible query. - if (flags & ANDROID_RESOLV_NO_CACHE_STORE) { - return RESOLV_CACHE_SKIP; - } - if (!cache_has_pending_request_locked(cache, &key, true)) { return RESOLV_CACHE_NOTFOUND; diff --git a/resolv/res_send.cpp b/resolv/res_send.cpp index 1ccfc741..1dff2038 100644 --- a/resolv/res_send.cpp +++ b/resolv/res_send.cpp @@ -931,6 +931,9 @@ read_len: else break; } + LOG(WARNING) << __func__ << ": resplen " << resplen << " exceeds buf size " << anssiz; + // return size should never exceed container size + resplen = anssiz; } /* * If the calling application has bailed out of @@ -941,7 +944,7 @@ read_len: */ if (hp->id != anhp->id) { LOG(DEBUG) << __func__ << ": ld answer (unexpected):"; - res_pquery(ans, (resplen > anssiz) ? anssiz : resplen); + res_pquery(ans, resplen); goto read_len; } diff --git a/server/AndroidTest.xml b/server/AndroidTest.xml index 2501d781..fbb0be72 100644 --- a/server/AndroidTest.xml +++ b/server/AndroidTest.xml @@ -14,6 +14,7 @@ limitations under the License. --> <configuration description="Config for netd_unit_test"> + <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/> <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> <option name="cleanup" value="true" /> <option name="push" value="netd_unit_test->/data/local/tmp/netd_unit_test" /> |