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

Commit 79701715 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "[Test] verify INetd::setNetworkAllowlist on DNS" am: 170eb6eb

parents 4b9a9ef7 170eb6eb
Loading
Loading
Loading
Loading
+151 −0
Original line number Diff line number Diff line
@@ -103,7 +103,9 @@ using aidl::android::net::IDnsResolver;
using aidl::android::net::INetd;
using aidl::android::net::ResolverOptionsParcel;
using aidl::android::net::ResolverParamsParcel;
using aidl::android::net::UidRangeParcel;
using aidl::android::net::metrics::INetdEventListener;
using aidl::android::net::netd::aidl::NativeUidRangeConfig;
using aidl::android::net::resolv::aidl::DnsHealthEventParcel;
using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener;
using aidl::android::net::resolv::aidl::Nat64PrefixEventParcel;
@@ -7034,6 +7036,20 @@ class ResolverMultinetworkTest : public ResolverTest {
            }
            return {};
        }

        Result<void> addUserFromParcel(uid_t uid, int32_t subPriority) const {
            return addUidRangeFromParcel(uid, uid, subPriority);
        }

        Result<void> addUidRangeFromParcel(uid_t from, uid_t to, int32_t subPriority) const {
            NativeUidRangeConfig cfg =
                    makeNativeUidRangeConfig(mNetId, {makeUidRangeParcel(from, to)}, subPriority);
            if (auto r = mNetdSrv->networkAddUidRangesParcel(cfg); !r.isOk()) {
                return Error() << r.getMessage();
            }
            return {};
        }

        const std::string& ifname() { return mIfname; }
        // Assuming mNetId is unique during ResolverMultinetworkTest, make the
        // address based on it to avoid conflicts.
@@ -7202,6 +7218,17 @@ class ResolverMultinetworkTest : public ResolverTest {
        dnsServer->clearQueries();
    }

    static NativeUidRangeConfig makeNativeUidRangeConfig(unsigned netId,
                                                         std::vector<UidRangeParcel> uidRanges,
                                                         int32_t subPriority) {
        NativeUidRangeConfig res;
        res.netId = netId;
        res.uidRanges = std::move(uidRanges);
        res.subPriority = subPriority;

        return res;
    }

  private:
    // Use a different netId because this class inherits from the class ResolverTest which
    // always creates TEST_NETID in setup. It's incremented when CreateScoped{Physical,
@@ -7356,6 +7383,11 @@ void expectDnsWorksForUid(const char* name, unsigned netId, uid_t uid,
    EXPECT_THAT(result_strs, testing::UnorderedElementsAreArray(expectedResult));
}

void expectDnsFailedForUid(const char* name, unsigned netId, uid_t uid) {
    ScopedChangeUID scopedChangeUID(uid);
    ASSERT_FALSE(android_getaddrinfofornet_wrapper(name, netId).ok());
}

}  // namespace

TEST_F(ResolverMultinetworkTest, GetAddrInfo_AI_ADDRCONFIG) {
@@ -7887,3 +7919,122 @@ TEST_F(ResolverTest, NetworkUnspecified_localhost) {
    EXPECT_TRUE(result != nullptr);
    EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
}

// Verify uid-based network permission on DNS, which is controlled by INetd::setNetworkAllowlist().
//
// Scenario:
// 1. There are three neworks at the same time:
//  - system default network
//  - enterprise network #1
//  - enterprise network #2
//
// 2. Simulate ConnectivityService calling INetd::setNetworkAllowlist so that
//  - TEST_UID can select only enterprise network #1 and #2. Can not select system default network.
//  - TEST_UID2 is unrestricted on all networks.
TEST_F(ResolverMultinetworkTest, UidAllowedNetworks) {
    // Netd supports it from v13.
    SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.netdService(), 13);

    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(fmt::format("ConnectivityType: {}", ipVersion));

        // Create networks.
        ScopedPhysicalNetwork sysDefaultNetwork =
                CreateScopedPhysicalNetwork(ipVersion, "SysDefault");
        ScopedPhysicalNetwork enterpriseNetwork_1 =
                CreateScopedPhysicalNetwork(ipVersion, "enterprise_1");
        ScopedPhysicalNetwork enterpriseNetwork_2 =
                CreateScopedPhysicalNetwork(ipVersion, "enterprise_2");
        ASSERT_RESULT_OK(sysDefaultNetwork.init());
        ASSERT_RESULT_OK(enterpriseNetwork_1.init());
        ASSERT_RESULT_OK(enterpriseNetwork_2.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 enterpriseNw1DnsSv =
                setupDns(ipVersion, &enterpriseNetwork_1, host_name, ipv4_addr, ipv6_addr);
        ASSERT_RESULT_OK(enterpriseNw1DnsSv);
        auto enterpriseNw2DnsSv =
                setupDns(ipVersion, &enterpriseNetwork_2, host_name, ipv4_addr, ipv6_addr);
        ASSERT_RESULT_OK(enterpriseNw2DnsSv);

        const unsigned systemDefaultNetId = sysDefaultNetwork.netId();
        const unsigned enterprise1NetId = enterpriseNetwork_1.netId();
        const unsigned enterprise2NetId = enterpriseNetwork_2.netId();

        setDefaultNetwork(systemDefaultNetId);

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

        // Add profile app default network for UID. DNS should be sent on it.
        // Note: subPriority 20 = PREFERENCE_ORDER_PROFILE, which is defined
        // in ConnectivityService.java. The value here doesn't really matter.
        ASSERT_RESULT_OK(enterpriseNetwork_1.addUserFromParcel(TEST_UID, /*subPriority*/ 20));
        expectDnsWorksForUid(host_name, NETID_UNSET, TEST_UID, expectedDnsReply);
        expectDnsQueryCountsFn(*enterpriseNw1DnsSv, host_name, expectedDnsReply.size(),
                               enterprise1NetId);

        // Set allowed networks for UIDs. To simplify test, assumes overall UID range is
        // {0, 1, 2, ..., TEST_UID2, TEST_UID}.
        // TEST_UID can't select the system default network. 0 - TEST_UID2 are allowed.
        NativeUidRangeConfig nwDefaultUserConfig = makeNativeUidRangeConfig(
                systemDefaultNetId, {makeUidRangeParcel(0, TEST_UID2)}, /*unused*/ 0);
        // All UIDs can select the enterprise network #1. 0 - TEST_UID are allowed.
        NativeUidRangeConfig nw1UserConfig = makeNativeUidRangeConfig(
                enterprise1NetId, {makeUidRangeParcel(0, TEST_UID)}, /*unused*/ 0);
        // All UIDs can select the enterprise network #2. 0 - TEST_UID are allowed.
        NativeUidRangeConfig nw2UserConfig = makeNativeUidRangeConfig(
                enterprise2NetId, {makeUidRangeParcel(0, TEST_UID)}, /*unused*/ 0);
        EXPECT_TRUE(
                mDnsClient.netdService()
                        ->setNetworkAllowlist({nwDefaultUserConfig, nw1UserConfig, nw2UserConfig})
                        .isOk());

        // Verify that DNS is behaving as the setting.
        struct TestConfig {
            int uid;
            const ScopedNetwork& selectedNetwork;
            bool expectedSuccess;
        } configs[]{
                // clang-format off
                {TEST_UID, sysDefaultNetwork, false},
                {TEST_UID, enterpriseNetwork_1, true},
                {TEST_UID, enterpriseNetwork_2, true},
                {TEST_UID2, sysDefaultNetwork, true},
                {TEST_UID2, enterpriseNetwork_1, true},
                {TEST_UID2, enterpriseNetwork_2, true},
                // clang-format on
        };
        for (const auto& cfg : configs) {
            SCOPED_TRACE(fmt::format("Dns over UID {}, selectedNetwork {}", cfg.uid,
                                     cfg.selectedNetwork.name()));
            if (cfg.expectedSuccess) {
                expectDnsWorksForUid(host_name, cfg.selectedNetwork.netId(), cfg.uid,
                                     expectedDnsReply);
            } else {
                expectDnsFailedForUid(host_name, cfg.selectedNetwork.netId(), cfg.uid);
            }
        }

        // Clear network restrictions.
        EXPECT_TRUE(mDnsClient.netdService()->setNetworkAllowlist({}).isOk());
        // TEST_UID and TEST_UID2 can both select all networks.
        for (const auto& cfg : configs) {
            SCOPED_TRACE(fmt::format("Dns over UID {}, selectedNetwork {}", cfg.uid,
                                     cfg.selectedNetwork.name()));
            expectDnsWorksForUid(host_name, cfg.selectedNetwork.netId(), cfg.uid, expectedDnsReply);
        }
    }
}