Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3cba8b62 authored by Luke Huang's avatar Luke Huang Committed by Automerger Merge Worker
Browse files

Merge "Make uid related tests compatible with Android Q" am: 05a0868b am:...

Merge "Make uid related tests compatible with Android Q" am: 05a0868b am: 2592a134 am: bf977624

Original change: https://android-review.googlesource.com/c/platform/packages/modules/DnsResolver/+/1381536

Change-Id: I6c5935e5d155d37b861433ce937d1dee654c4d3a
parents fd9ff410 bf977624
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -17,26 +17,20 @@
#include "DnsResolver.h"

#include <android-base/logging.h>
#include <android-base/properties.h>

#include "DnsProxyListener.h"
#include "DnsResolverService.h"
#include "netd_resolv/resolv.h"
#include "res_debug.h"
#include "util.h"

bool resolv_init(const ResolverNetdCallbacks* callbacks) {
    android::base::InitLogging(/*argv=*/nullptr);
    android::base::SetDefaultTag("libnetd_resolv");
    LOG(INFO) << __func__ << ": Initializing resolver";
    resolv_set_log_severity(android::base::WARNING);

    uint64_t buildVersionSdk = android::base::GetUintProperty<uint64_t>("ro.build.version.sdk", 0);
    uint64_t buildVersionPreviewSdk =
            android::base::GetUintProperty<uint64_t>("ro.build.version.preview_sdk", 0);
    uint64_t firstApiLevel =
            android::base::GetUintProperty<uint64_t>("ro.product.first_api_level", 0);
    using android::net::gApiLevel;
    gApiLevel = std::max(buildVersionSdk + !!buildVersionPreviewSdk, firstApiLevel);
    gApiLevel = getApiLevel();
    using android::net::gResNetdCallbacks;
    gResNetdCallbacks.check_calling_permission = callbacks->check_calling_permission;
    gResNetdCallbacks.get_network_context = callbacks->get_network_context;
+49 −24
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@
#include <aidl/android/net/IDnsResolver.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <util.h>  // getApiLevel
#include "NetdClient.h"
#include "ResolverStats.h"
#include "netid_client.h"  // NETID_UNSET
@@ -162,6 +163,8 @@ class ScopedSystemProperties {
    std::string mStoredValue;
};

const bool isAtLeastR = (getApiLevel() >= 30);

}  // namespace

class ResolverTest : public ::testing::Test {
@@ -4120,17 +4123,24 @@ TEST_F(ResolverTest, BlockDnsQueryWithUidRule) {
    EXPECT_TRUE(fd1 != -1);
    EXPECT_TRUE(fd2 != -1);

    uint8_t buf[MAXPACKET] = {};
    uint8_t buf1[MAXPACKET] = {};
    uint8_t buf2[MAXPACKET] = {};
    int rcode;
    int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
    EXPECT_EQ(-ECONNREFUSED, res);

    memset(buf, 0, MAXPACKET);
    res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
    EXPECT_EQ(-ECONNREFUSED, res);

    int res2 = getAsyncResponse(fd2, &rcode, buf2, MAXPACKET);
    int res1 = getAsyncResponse(fd1, &rcode, buf1, MAXPACKET);
    // If API level >= 30 (R+), these queries should be blocked.
    if (isAtLeastR) {
        EXPECT_EQ(res2, -ECONNREFUSED);
        EXPECT_EQ(res1, -ECONNREFUSED);
        ExpectDnsEvent(INetdEventListener::EVENT_RES_NSEND, EAI_SYSTEM, "howdy.example.com", {});
        ExpectDnsEvent(INetdEventListener::EVENT_RES_NSEND, EAI_SYSTEM, "howdy.example.com", {});
    } else {
        EXPECT_GT(res2, 0);
        EXPECT_EQ("::1.2.3.4", toString(buf2, res2, AF_INET6));
        EXPECT_GT(res1, 0);
        EXPECT_EQ("1.2.3.4", toString(buf1, res1, AF_INET));
        // To avoid flaky test, do not evaluate DnsEvent since event order is not guaranteed.
    }
}

TEST_F(ResolverTest, EnforceDnsUid) {
@@ -4156,23 +4166,31 @@ TEST_F(ResolverTest, EnforceDnsUid) {
    ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(parcel).isOk());

    uint8_t buf[MAXPACKET] = {};
    uint8_t buf2[MAXPACKET] = {};
    int rcode;
    {
        ScopeBlockedUIDRule scopeBlockUidRule(netdService, TEST_UID);
        // Dns Queries should be blocked
        int fd1 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_a, 0);
        int fd2 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_aaaa, 0);
        const int fd1 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_a, 0);
        const int fd2 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_aaaa, 0);
        EXPECT_TRUE(fd1 != -1);
        EXPECT_TRUE(fd2 != -1);

        int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
        EXPECT_EQ(-ECONNREFUSED, res);

        memset(buf, 0, MAXPACKET);
        res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
        EXPECT_EQ(-ECONNREFUSED, res);
        const int res2 = getAsyncResponse(fd2, &rcode, buf2, MAXPACKET);
        const int res1 = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
        // If API level >= 30 (R+), the query should be blocked.
        if (isAtLeastR) {
            EXPECT_EQ(res2, -ECONNREFUSED);
            EXPECT_EQ(res1, -ECONNREFUSED);
        } else {
            EXPECT_GT(res2, 0);
            EXPECT_EQ("::1.2.3.4", toString(buf2, res2, AF_INET6));
            EXPECT_GT(res1, 0);
            EXPECT_EQ("1.2.3.4", toString(buf, res1, AF_INET));
        }
    }

    memset(buf, 0, MAXPACKET);
    parcel.resolverOptions.enforceDnsUid = true;
    ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(parcel).isOk());
    {
@@ -5168,16 +5186,23 @@ TEST_F(ResolverTest, BlockDnsQueryUidDoesNotLeadToBadServer) {
        for (int i = 0; i < 10; i++) {
            std::string hostName = fmt::format("blocked{}.com", i);
            const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
            EXPECT_EQ(safe_getaddrinfo(hostName.c_str(), nullptr, &hints), nullptr);
            // The query result between R+ and Q would be different, but we don't really care
            // about the result here because this test is only used to ensure blocked uid rule
            // won't cause bad servers.
            safe_getaddrinfo(hostName.c_str(), nullptr, &hints);
        }
    }
    // Since all query packets are blocked, we should not see any stats of them.
    const std::vector<NameserverStats> expectedEmptyDnsStats = {
            NameserverStats(listen_addr1),
    ResolverParamsParcel setupParams = DnsResponderClient::GetDefaultResolverParamsParcel();
    // If api level >= 30 (R+), expect all query packets to be blocked, hence we should not see any
    // of their stats show up. Otherwise, all queries should succeed.
    const std::vector<NameserverStats> expectedDnsStats = {
            NameserverStats(listen_addr1).setSuccesses(isAtLeastR ? 0 : setupParams.maxSamples),
            NameserverStats(listen_addr2),
    };
    expectStatsEqualTo(expectedEmptyDnsStats);
    EXPECT_EQ(dns1.queries().size(), 0U);
    expectStatsEqualTo(expectedDnsStats);
    // If api level >= 30 (R+), expect server won't receive any queries,
    // otherwise expect 20 == 10 * (setupParams.domains.size() + 1) queries.
    EXPECT_EQ(dns1.queries().size(), isAtLeastR ? 0U : 10 * (setupParams.domains.size() + 1));
    EXPECT_EQ(dns2.queries().size(), 0U);
}

+20 −0
Original line number Diff line number Diff line
@@ -21,9 +21,29 @@

#include <netinet/in.h>

#include <android-base/properties.h>

socklen_t sockaddrSize(const sockaddr* sa);
socklen_t sockaddrSize(const sockaddr_storage& ss);

// TODO: getExperimentFlagString
// TODO: Migrate it to DnsResolverExperiments.cpp
int getExperimentFlagInt(const std::string& flagName, int defaultValue);

// When sdk X release branch is created, aosp's sdk version would still be X-1,
// internal would be X. Also there might be some different setting between real devices and
// CF. Below is the example for the sdk related properties in later R development stage. (internal
// should be cosidered as S and aosp should be considered as R.)
// R version is 30,                          rvc-dev  aosp(CF)  aosp(non-CF)  internal
// ro.build.version.sdk:                     [30]     [29]      [29]          [30]
// Note that, ro.product.first_api_level is device specific - so the value might be various.
// ro.product.first_api_level:               [26-30]  [31]      [28]          [26-30]
// ro.build.version.preview_sdk:             [0]      [1]       [1]           [1]
inline uint64_t getApiLevel() {
    uint64_t buildVersionSdk = android::base::GetUintProperty<uint64_t>("ro.build.version.sdk", 0);
    uint64_t buildVersionPreviewSdk =
            android::base::GetUintProperty<uint64_t>("ro.build.version.preview_sdk", 0);
    uint64_t firstApiLevel =
            android::base::GetUintProperty<uint64_t>("ro.product.first_api_level", 0);
    return std::max(buildVersionSdk + !!buildVersionPreviewSdk, firstApiLevel);
}