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

Commit 71300d18 authored by Luke Huang's avatar Luke Huang Committed by Automerger Merge Worker
Browse files

Merge "Fix the unexpected getaddrinfo error code changing due to parallel lookup" am: 8f58a580

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

Change-Id: I917d50414c4f0dc8102160dbc8931ea07740c01a
parents 6ab46595 8f58a580
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -1603,6 +1603,7 @@ struct QueryResult {
    int ancount;
    int rcode;
    int herrno;
    int qerrno;
    NetworkDnsEventReported event;
};

@@ -1635,6 +1636,7 @@ QueryResult doQuery(const char* name, res_target* t, res_state res,
                .ancount = 0,
                .rcode = -1,
                .herrno = NO_RECOVERY,
                .qerrno = errno,
                .event = event,
        };
    }
@@ -1644,13 +1646,15 @@ QueryResult doQuery(const char* name, res_target* t, res_state res,
    int rcode = NOERROR;
    n = res_nsend(&res_temp, buf, n, t->answer.data(), anslen, &rcode, 0, sleepTimeMs);
    if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
        // To ensure that the rcode handling is identical to res_queryN().
        if (rcode != RCODE_TIMEOUT) rcode = hp->rcode;
        // if the query choked with EDNS0, retry without EDNS0
        if ((res_temp.netcontext_flags &
             (NET_CONTEXT_FLAG_USE_DNS_OVER_TLS | NET_CONTEXT_FLAG_USE_EDNS)) &&
            (res_temp._flags & RES_F_EDNS0ERR)) {
            LOG(DEBUG) << __func__ << ": retry without EDNS0";
            n = res_nmkquery(QUERY, name, cl, type, /*data=*/nullptr, /*datalen=*/0, buf,
                             sizeof(buf), res->netcontext_flags);
                             sizeof(buf), res_temp.netcontext_flags);
            n = res_nsend(&res_temp, buf, n, t->answer.data(), anslen, &rcode, 0);
        }
    }
@@ -1661,6 +1665,7 @@ QueryResult doQuery(const char* name, res_target* t, res_state res,
    return {
            .ancount = ntohs(hp->ancount),
            .rcode = rcode,
            .qerrno = errno,
            .event = event,
    };
}
@@ -1695,6 +1700,7 @@ static int res_queryN_parallel(const char* name, res_target* target, res_state r
        res->event->MergeFrom(r.event);
        ancount += r.ancount;
        rcode = r.rcode;
        errno = r.qerrno;
    }

    if (ancount == 0) {
+50 −0
Original line number Diff line number Diff line
@@ -4249,6 +4249,56 @@ TEST_F(ResolverTest, BlockDnsQueryWithUidRule) {
    }
}

TEST_F(ResolverTest, GetAddrinfo_BlockDnsQueryWithUidRule) {
    SKIP_IF_BPF_NOT_SUPPORTED;
    constexpr char listen_addr1[] = "127.0.0.4";
    constexpr char listen_addr2[] = "::1";
    constexpr char host_name[] = "howdy.example.com.";
    const std::vector<DnsRecord> records = {
            {host_name, ns_type::ns_t_a, "1.2.3.4"},
            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
    };
    test::DNSResponder dns1(listen_addr1);
    test::DNSResponder dns2(listen_addr2);
    StartDns(dns1, records);
    StartDns(dns2, records);

    std::vector<std::string> servers = {listen_addr1, listen_addr2};
    ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains, kDefaultParams));

    const addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_DGRAM};

    static struct {
        const char* hname;
        const int expectedErrorCode;
    } kTestData[] = {
            {host_name, EAI_NODATA},
            // To test the query with search domain.
            {"howdy", EAI_AGAIN},
    };

    INetd* netdService = mDnsClient.netdService();
    for (auto& td : kTestData) {
        SCOPED_TRACE(td.hname);
        ScopeBlockedUIDRule scopeBlockUidRule(netdService, TEST_UID);
        // If API level >= 30 (R+), these queries should be blocked.
        if (isAtLeastR) {
            addrinfo* result = nullptr;
            // getaddrinfo() in bionic would convert all errors to EAI_NODATA
            // except EAI_SYSTEM.
            EXPECT_EQ(EAI_NODATA, getaddrinfo(td.hname, nullptr, &hints, &result));
            ExpectDnsEvent(INetdEventListener::EVENT_GETADDRINFO, td.expectedErrorCode, td.hname,
                           {});
        } else {
            ScopedAddrinfo result = safe_getaddrinfo(td.hname, nullptr, &hints);
            EXPECT_NE(nullptr, result);
            EXPECT_THAT(ToStrings(result),
                        testing::UnorderedElementsAreArray({"1.2.3.4", "::1.2.3.4"}));
            // To avoid flaky test, do not evaluate DnsEvent since event order is not guaranteed.
        }
    }
}

TEST_F(ResolverTest, EnforceDnsUid) {
    SKIP_IF_BPF_NOT_SUPPORTED;
    constexpr char listen_addr1[] = "127.0.0.4";