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

Commit 931f2837 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 7563205 from d8e66e6d to tm-release

Change-Id: I4372fac36e509aa6c97fc8846e3c05f8d2a15015
parents 19852864 d8e66e6d
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -400,7 +400,8 @@ rust_ffi_static {
        "liburl",
    ],
    prefer_rlib: true,

    // For unit tests to run on the Android 10 platform, libunwind must be statically linked..
    whole_static_libs: ["libunwind"],
    apex_available: [
        "//apex_available:platform",  // Needed by doh_ffi_test
        "com.android.resolv"
+150 −48
Original line number Diff line number Diff line
@@ -6427,6 +6427,14 @@ class ResolverMultinetworkTest : public ResolverTest {
        bool clearDnsConfiguration() const;
        unsigned netId() const { return mNetId; }
        std::string name() const { return mNetworkName; }
        Result<void> addUser(uid_t uid) const { return addUidRange(uid, uid); }
        Result<void> addUidRange(uid_t from, uid_t to) const {
            if (auto r = mNetdSrv->networkAddUidRanges(mNetId, {makeUidRangeParcel(from, to)});
                !r.isOk()) {
                return Error() << r.getMessage();
            }
            return {};
        }

      protected:
        // Subclasses should implement it to decide which network should be create.
@@ -6510,14 +6518,6 @@ class ResolverMultinetworkTest : public ResolverTest {
            mVpnIsolationUids.erase(uid);
            return {};
        }
        Result<void> addUser(uid_t uid) const { return addUidRange(uid, uid); }
        Result<void> addUidRange(uid_t from, uid_t to) const {
            if (auto r = mNetdSrv->networkAddUidRanges(mNetId, {makeUidRangeParcel(from, to)});
                !r.isOk()) {
                return Error() << r.getMessage();
            }
            return {};
        }

      protected:
        Result<void> createNetwork() const override {
@@ -6578,6 +6578,17 @@ class ResolverMultinetworkTest : public ResolverTest {
        if (mNextNetId == TEST_NETID_BASE + 256) mNextNetId = TEST_NETID_BASE;
        return mNextNetId++;
    }
    Result<std::shared_ptr<test::DNSResponder>> setupDns(ConnectivityType type, ScopedNetwork* nw,
                                                         const char* host_name,
                                                         const char* ipv4_addr,
                                                         const char* ipv6_addr);

    void expectDnsQueryCountsFn(std::shared_ptr<test::DNSResponder> dnsServer,
                                const char* host_name, size_t count, unsigned expectedDnsNetId) {
        EXPECT_EQ(GetNumQueries(*dnsServer, host_name), count);
        EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(expectedDnsNetId).isOk());
        dnsServer->clearQueries();
    }

  private:
    // Use a different netId because this class inherits from the class ResolverTest which
@@ -6643,6 +6654,21 @@ void ResolverMultinetworkTest::StartDns(test::DNSResponder& dns,
    }
}

Result<std::shared_ptr<test::DNSResponder>> ResolverMultinetworkTest::setupDns(
        ConnectivityType type, ScopedNetwork* nw, const char* host_name, const char* ipv4_addr,
        const char* ipv6_addr) {
    // Add a testing DNS server to networks.
    const Result<DnsServerPair> dnsSvPair =
            (type == ConnectivityType::V4) ? nw->addIpv4Dns() : nw->addIpv6Dns();
    if (!dnsSvPair.ok()) return Error() << dnsSvPair.error();

    StartDns(*dnsSvPair->dnsServer,
             {{host_name, ns_type::ns_t_a, ipv4_addr}, {host_name, ns_type::ns_t_aaaa, ipv6_addr}});
    if (!nw->setDnsConfiguration()) return Error() << "setDnsConfiguration() failed";
    if (!nw->startTunForwarder()) return Error() << "startTunForwarder() failed";
    return dnsSvPair->dnsServer;
}

Result<ResolverMultinetworkTest::DnsServerPair> ResolverMultinetworkTest::ScopedNetwork::addDns(
        ConnectivityType type) {
    const int index = mDnsServerPairs.size();
@@ -6875,30 +6901,15 @@ TEST_F(ResolverMultinetworkTest, DnsWithVpn) {
        ASSERT_RESULT_OK(bypassableVpnNetwork.addUser(TEST_UID));
        ASSERT_RESULT_OK(secureVpnNetwork.addUser(TEST_UID2));

        auto setupDnsFn = [&](std::shared_ptr<test::DNSResponder> dnsServer,
                              ScopedNetwork* nw) -> void {
            StartDns(*dnsServer, {{host_name, ns_type::ns_t_a, ipv4_addr},
                                  {host_name, ns_type::ns_t_aaaa, ipv6_addr}});
            ASSERT_TRUE(nw->setDnsConfiguration());
            ASSERT_TRUE(nw->startTunForwarder());
        };
        // Add a testing DNS server to networks.
        const Result<DnsServerPair> underlyingPair = (type == ConnectivityType::V4)
                                                             ? underlyingNetwork.addIpv4Dns()
                                                             : underlyingNetwork.addIpv6Dns();
        ASSERT_RESULT_OK(underlyingPair);
        const Result<DnsServerPair> bypassableVpnPair = (type == ConnectivityType::V4)
                                                                ? bypassableVpnNetwork.addIpv4Dns()
                                                                : bypassableVpnNetwork.addIpv6Dns();
        ASSERT_RESULT_OK(bypassableVpnPair);
        const Result<DnsServerPair> secureVpnPair = (type == ConnectivityType::V4)
                                                            ? secureVpnNetwork.addIpv4Dns()
                                                            : secureVpnNetwork.addIpv6Dns();
        ASSERT_RESULT_OK(secureVpnPair);
        // Set up resolver and start forwarding for networks.
        setupDnsFn(underlyingPair->dnsServer, &underlyingNetwork);
        setupDnsFn(bypassableVpnPair->dnsServer, &bypassableVpnNetwork);
        setupDnsFn(secureVpnPair->dnsServer, &secureVpnNetwork);
        auto underlyingNwDnsSv =
                setupDns(type, &underlyingNetwork, host_name, ipv4_addr, ipv6_addr);
        ASSERT_RESULT_OK(underlyingNwDnsSv);
        auto bypassableVpnDnsSv =
                setupDns(type, &bypassableVpnNetwork, host_name, ipv4_addr, ipv6_addr);
        ASSERT_RESULT_OK(bypassableVpnDnsSv);
        auto secureVpnDnsSv = setupDns(type, &secureVpnNetwork, host_name, ipv4_addr, ipv6_addr);
        ASSERT_RESULT_OK(secureVpnDnsSv);

        setDefaultNetwork(underlyingNetwork.netId());
        const unsigned underlyingNetId = underlyingNetwork.netId();
@@ -6906,15 +6917,6 @@ TEST_F(ResolverMultinetworkTest, DnsWithVpn) {
        const unsigned secureVpnNetId = secureVpnNetwork.netId();
        // We've called setNetworkForProcess in SetupOemNetwork, so reset to default first.
        ScopedSetNetworkForProcess scopedSetNetworkForProcess(NETID_UNSET);
        auto expectDnsQueryCountsFn = [&](size_t count,
                                          std::shared_ptr<test::DNSResponder> dnsServer,
                                          unsigned expectedDnsNetId) -> void {
            EXPECT_EQ(GetNumQueries(*dnsServer, host_name), count);
            EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(expectedDnsNetId).isOk());
            dnsServer->clearQueries();
            // Give DnsResolver some time to clear cache to avoid race.
            usleep(5 * 1000);
        };

        // Create a object to represent default network, do not init it.
        ScopedPhysicalNetwork defaultNetwork{NETID_UNSET, "Default"};
@@ -6928,20 +6930,20 @@ TEST_F(ResolverMultinetworkTest, DnsWithVpn) {
        } vpnWithDnsServerConfigs[]{
                // clang-format off
                // Queries use the bypassable VPN by default.
                {&defaultNetwork,       bypassableVpnNetId, bypassableVpnPair->dnsServer},
                {&defaultNetwork,       bypassableVpnNetId, *bypassableVpnDnsSv},
                // Choosing the underlying network works because the VPN is bypassable.
                {&underlyingNetwork,    underlyingNetId,    underlyingPair->dnsServer},
                {&underlyingNetwork,    underlyingNetId,    *underlyingNwDnsSv},
                // Selecting the VPN sends the query on the VPN.
                {&bypassableVpnNetwork, bypassableVpnNetId, bypassableVpnPair->dnsServer},
                {&bypassableVpnNetwork, bypassableVpnNetId, *bypassableVpnDnsSv},
                // TEST_UID does not have access to the secure VPN.
                {&secureVpnNetwork,     bypassableVpnNetId, bypassableVpnPair->dnsServer},
                {&secureVpnNetwork,     bypassableVpnNetId, *bypassableVpnDnsSv},
                // clang-format on
        };
        for (const auto& config : vpnWithDnsServerConfigs) {
            SCOPED_TRACE(fmt::format("Bypassble VPN with DnsServer, selectedNetwork = {}",
                                     config.selectedNetwork->name()));
            expectDnsWorksForUid(host_name, config.selectedNetwork->netId(), TEST_UID, result);
            expectDnsQueryCountsFn(result.size(), config.expectedDnsServer,
            expectDnsQueryCountsFn(config.expectedDnsServer, host_name, result.size(),
                                   config.expectedDnsNetId);
        }

@@ -6954,7 +6956,7 @@ TEST_F(ResolverMultinetworkTest, DnsWithVpn) {
            SCOPED_TRACE(fmt::format("Bypassble VPN without DnsServer, selectedNetwork = {}",
                                     selectedNetwork->name()));
            expectDnsWorksForUid(host_name, selectedNetwork->netId(), TEST_UID, result);
            expectDnsQueryCountsFn(result.size(), underlyingPair->dnsServer, underlyingNetId);
            expectDnsQueryCountsFn(*underlyingNwDnsSv, host_name, result.size(), underlyingNetId);
        }

        // The same test scenario as before plus enableVpnIsolation for secure VPN, TEST_UID2.
@@ -6970,7 +6972,8 @@ TEST_F(ResolverMultinetworkTest, DnsWithVpn) {
                SCOPED_TRACE(fmt::format("Secure VPN without DnsServer, selectedNetwork = {}",
                                         selectedNetwork->name()));
                expectDnsWorksForUid(host_name, selectedNetwork->netId(), TEST_UID2, result);
                expectDnsQueryCountsFn(result.size(), underlyingPair->dnsServer, underlyingNetId);
                expectDnsQueryCountsFn(*underlyingNwDnsSv, host_name, result.size(),
                                       underlyingNetId);
            }

            // Test secure VPN with DNS server.
@@ -6979,7 +6982,7 @@ TEST_F(ResolverMultinetworkTest, DnsWithVpn) {
                SCOPED_TRACE(fmt::format("Secure VPN with DnsServer, selectedNetwork = {}",
                                         selectedNetwork->name()));
                expectDnsWorksForUid(host_name, selectedNetwork->netId(), TEST_UID2, result);
                expectDnsQueryCountsFn(result.size(), secureVpnPair->dnsServer, secureVpnNetId);
                expectDnsQueryCountsFn(*secureVpnDnsSv, host_name, result.size(), secureVpnNetId);
            }

            if (enableVpnIsolation) {
@@ -6988,3 +6991,102 @@ TEST_F(ResolverMultinetworkTest, DnsWithVpn) {
        }
    }
}

// verify per-application default network selection on DNS.
TEST_F(ResolverMultinetworkTest, PerAppDefaultNetwork) {
    // Netd supports uid ranges on physical network from v6.
    SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.netdService(), 6);

    constexpr char host_name[] = "ohayou.example.com.";
    constexpr char ipv4_addr[] = "192.0.2.0";
    constexpr char ipv6_addr[] = "2001:db8:cafe:d00d::31";

    const std::pair<ConnectivityType, std::vector<std::string>> testPairs[] = {
            {ConnectivityType::V4, {ipv4_addr}},
            {ConnectivityType::V6, {ipv6_addr}},
            {ConnectivityType::V4V6, {ipv6_addr, ipv4_addr}},
    };
    for (const auto& [ipVersion, expectedDnsReply] : testPairs) {
        SCOPED_TRACE(StringPrintf("ConnectivityType: %d", ipVersion));

        // Create networks.
        ScopedPhysicalNetwork sysDefaultNetwork =
                CreateScopedPhysicalNetwork(ipVersion, "SysDefault");
        ScopedPhysicalNetwork appDefaultNetwork =
                CreateScopedPhysicalNetwork(ipVersion, "AppDefault");
        ScopedVirtualNetwork vpn = CreateScopedVirtualNetwork(ipVersion, false, "Vpn");

        ASSERT_RESULT_OK(sysDefaultNetwork.init());
        ASSERT_RESULT_OK(appDefaultNetwork.init());
        ASSERT_RESULT_OK(vpn.init());

        // Set up resolver and start forwarding for networks.
        auto sysDefaultNwDnsSv =
                setupDns(ipVersion, &sysDefaultNetwork, host_name, ipv4_addr, ipv6_addr);
        ASSERT_RESULT_OK(sysDefaultNwDnsSv);
        auto appDefaultNwDnsSv =
                setupDns(ipVersion, &appDefaultNetwork, host_name, ipv4_addr, ipv6_addr);
        ASSERT_RESULT_OK(appDefaultNwDnsSv);
        auto vpnDnsSv = setupDns(ipVersion, &vpn, host_name, ipv4_addr, ipv6_addr);
        ASSERT_RESULT_OK(vpnDnsSv);

        const unsigned systemDefaultNetId = sysDefaultNetwork.netId();
        const unsigned appDefaultNetId = appDefaultNetwork.netId();
        const unsigned vpnNetId = vpn.netId();

        setDefaultNetwork(systemDefaultNetId);
        EXPECT_TRUE(
                mDnsClient.netdService()
                        ->networkSetPermissionForNetwork(appDefaultNetId, INetd::PERMISSION_SYSTEM)
                        .isOk());

        // We've called setNetworkForProcess in SetupOemNetwork, reset to default first.
        ScopedSetNetworkForProcess scopedSetNetworkForProcess(NETID_UNSET);

        // Test DNS query without selecting a network. --> use system default network.
        expectDnsWorksForUid(host_name, NETID_UNSET, TEST_UID, expectedDnsReply);
        expectDnsQueryCountsFn(*sysDefaultNwDnsSv, host_name, expectedDnsReply.size(),
                               systemDefaultNetId);
        // Add user to app default network. --> use app default network.
        ASSERT_RESULT_OK(appDefaultNetwork.addUser(TEST_UID));
        expectDnsWorksForUid(host_name, NETID_UNSET, TEST_UID, expectedDnsReply);
        expectDnsQueryCountsFn(*appDefaultNwDnsSv, host_name, expectedDnsReply.size(),
                               appDefaultNetId);

        // Test DNS query with a selected network.
        // App default network applies to uid, vpn does not applies to uid.
        const struct TestConfig {
            ScopedNetwork* selectedNetwork;
            unsigned expectedDnsNetId;
            std::shared_ptr<test::DNSResponder> expectedDnsServer;
        } vpnWithDnsServerConfigs[]{
                // clang-format off
                // App can select the system default network without any permission.
                {&sysDefaultNetwork, systemDefaultNetId, *sysDefaultNwDnsSv},
                // App can select the restricted network, since its uid was assigned to the network.
                {&appDefaultNetwork, appDefaultNetId, *appDefaultNwDnsSv},
                // App does not have access to the VPN. --> fallback to app default network.
                {&vpn, appDefaultNetId, *appDefaultNwDnsSv},
                // clang-format on
        };
        for (const auto& config : vpnWithDnsServerConfigs) {
            SCOPED_TRACE(fmt::format("Dns over app default network, selectedNetwork = {}",
                                     config.selectedNetwork->name()));
            expectDnsWorksForUid(host_name, config.selectedNetwork->netId(), TEST_UID,
                                 expectedDnsReply);
            expectDnsQueryCountsFn(config.expectedDnsServer, host_name, expectedDnsReply.size(),
                                   config.expectedDnsNetId);
        }

        // App default network applies to uid, vpn applies to uid. --> use vpn.
        ASSERT_RESULT_OK(vpn.addUser(TEST_UID));
        expectDnsWorksForUid(host_name, vpn.netId(), TEST_UID, expectedDnsReply);
        expectDnsQueryCountsFn(*vpnDnsSv, host_name, expectedDnsReply.size(), vpnNetId);

        // vpn without server. --> fallback to app default network.
        ASSERT_TRUE(vpn.clearDnsConfiguration());
        expectDnsWorksForUid(host_name, vpn.netId(), TEST_UID, expectedDnsReply);
        expectDnsQueryCountsFn(*appDefaultNwDnsSv, host_name, expectedDnsReply.size(),
                               appDefaultNetId);
    }
}