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

Commit 09c33ed3 authored by Kenny Chen's avatar Kenny Chen Committed by Automerger Merge Worker
Browse files

Merge changes I02545dbe,I37759a1b,Idff35a3d am: 5ad0ac0e

parents 97d22ba3 5ad0ac0e
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -331,3 +331,62 @@ cc_test {
    ],
    compile_multilib: "first",
}

cc_defaults {
    name: "resolv_fuzzer_defaults",
    defaults: [
        "netd_defaults",
        "resolv_test_defaults",
    ],
    srcs: [
        "doh_frontend.cpp",
    ],
    header_libs: [
        "libnetd_resolv_headers",
        "dnsproxyd_protocol_headers",
    ],
    shared_libs: [
        "libbinder_ndk",
    ],
    static_libs: [
        "dnsresolver_aidl_interface-lateststable-ndk",
        "libcrypto_static",
        "libdoh_fuzz_ffi",
        "libgtest",
        "libnetdutils",
        "libnetd_resolv",
        "libnetd_test_dnsresponder_ndk",
        "libnetd_test_resolv_utils",
        "libprotobuf-cpp-lite",
        "libssl",
        "libsysutils",
        "netd_aidl_interface-lateststable-ndk",
        "netd_event_listener_interface-lateststable-ndk",
        "server_configurable_flags",
        "stats_proto",
    ],
    fuzz_config: {
       cc: [
            "cken@google.com",
            "kfcchen@google.com",
       ],
    },
}

cc_fuzz {
    name: "resolv_gethostbyname_fuzzer",
    defaults: ["resolv_fuzzer_defaults"],
    srcs: ["fuzzer/resolv_gethostbyname_fuzzer.cpp"],
}

cc_fuzz {
    name: "resolv_gethostbyaddr_fuzzer",
    defaults: ["resolv_fuzzer_defaults"],
    srcs: ["fuzzer/resolv_gethostbyaddr_fuzzer.cpp"],
}

cc_fuzz {
    name: "resolv_getaddrinfo_fuzzer",
    defaults: ["resolv_fuzzer_defaults"],
    srcs: ["fuzzer/resolv_getaddrinfo_fuzzer.cpp"],
}
+112 −0
Original line number Diff line number Diff line
#ifndef RESOLV_FUZZER_UTILS_H_
#define RESOLV_FUZZER_UTILS_H_

#include <arpa/inet.h>  // for inet_pton
#include <fuzzer/FuzzedDataProvider.h>

#include "DnsResolver.h"
#include "Experiments.h"  // for update property
#include "ResolverController.h"
#include "dns_responder/dns_responder_client_ndk.h"
#include "dns_responder/dns_tls_frontend.h"
#include "doh.h"  // for DOH_LOG_LEVEL_DEBUG
#include "doh_frontend.h"
#include "getaddrinfo.h"
#include "gethnamaddr.h"
#include "res_debug.h"  // for resolv_set_log_severity
#include "resolv_cache.h"
#include "resolv_test_utils.h"

namespace android::net {

// TODO: Consider moving to packages/modules/DnsResolver/tests/resolv_test_utils.h.
constexpr int MAXPACKET = 8 * 1024;

// Tests A/AAAA/CNAME type and CNAME chain.
const std::vector<DnsRecord> records = {
        {kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4},
        {kHelloExampleCom, ns_type::ns_t_aaaa, kHelloExampleComAddrV6},
        {kCnameA, ns_type::ns_t_cname, kCnameB},
        {kCnameB, ns_type::ns_t_a, kHelloExampleComAddrV4},
        {kCnameC, ns_type::ns_t_cname, kCnameD},
};

const android_net_context mNetContext = {
        .app_netid = TEST_NETID,
        .app_mark = MARK_UNSET,
        .dns_netid = TEST_NETID,
        .dns_mark = MARK_UNSET,
        .uid = TEST_UID,
};

// Initializes servers to simulate the DNS over UDP/TLS/HTTPS.
test::DNSResponder dns{kDefaultServer, kDnsPortString};
test::DohFrontend doh{kDefaultServer, kDohPortString, "127.0.1.3", kDnsPortString};
test::DNSResponder doh_backend{"127.0.1.3", kDnsPortString};
test::DnsTlsFrontend dot{kDefaultServer, kDotPortString, "127.0.2.3", kDnsPortString};
test::DNSResponder dot_backend{"127.0.2.3", kDnsPortString};
ResolverController resolverCtrl;

// TODO: Consider moving to packages/modules/DnsResolver/tests/resolv_test_utils.h.
void StartDns(test::DNSResponder& dns, const std::vector<DnsRecord>& records) {
    for (const auto& r : records) {
        dns.addMapping(r.host_name, r.type, r.addr);
    }

    ASSERT_TRUE(dns.startServer());
    dns.clearQueries();
}

int RandomSocketType(FuzzedDataProvider& fdp) {
    int socktype = fdp.PickValueInArray(
            {SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_DCCP, SOCK_PACKET});
    if (fdp.ConsumeBool()) socktype |= SOCK_CLOEXEC;
    if (fdp.ConsumeBool()) socktype |= SOCK_NONBLOCK;
    return socktype;
}

// Initializes the callback functions to createNetworkCache.
void InitDnsResolverCallbacks() {
    gResNetdCallbacks.check_calling_permission = [](const char*) -> bool { return true; };
    gResNetdCallbacks.get_network_context = [](uint32_t, uint32_t, android_net_context*) {};
    gResNetdCallbacks.log = [](const char*) {};
}

void InitServers() {
    StartDns(dns, records);
    doh.startServer();
    StartDns(doh_backend, records);
    dot.startServer();
    StartDns(dot_backend, records);
}

void CleanServers() {
    dns.clearQueries();
    doh.clearQueries();
    doh_backend.clearQueries();
    dot.clearQueries();
    dot_backend.clearQueries();
}

// Initializes servers only one time.
bool DoInit() {
    // Sets log level to WARNING to lower I/O time cost.
    resolv_set_log_severity(android::base::WARNING);
    doh_init_logger(DOH_LOG_LEVEL_WARN);

    // Needs to init callback and create netework cache.
    InitDnsResolverCallbacks();
    resolverCtrl.createNetworkCache(TEST_NETID);
    InitServers();

    return true;
}

void CleanUp() {
    CleanServers();
    resolverCtrl.flushNetworkCache(TEST_NETID);
}

}  // namespace android::net

#endif  // RESOLV_FUZZER_UTILS_H_
+52 −0
Original line number Diff line number Diff line
#include "resolv_fuzzer_utils.h"

namespace android::net {
namespace {

// Tests resolv_getaddrinfo.
void TestResolvGetaddrinfo(FuzzedDataProvider& fdp) {
    std::string hostname = fdp.ConsumeRandomLengthString(MAXHOSTNAMELEN);
    std::string servname = fdp.ConsumeRandomLengthString(MAXHOSTNAMELEN);
    // All valid address families in socket.h, e.g. AF_INET.
    int af = fdp.ConsumeIntegralInRange<int>(0, AF_MAX);
    int socktype = RandomSocketType(fdp);
    addrinfo hints = {.ai_family = af, .ai_socktype = socktype};
    addrinfo* result;
    NetworkDnsEventReported event;

    resolv_getaddrinfo(hostname.c_str(), fdp.ConsumeBool() ? servname.c_str() : nullptr,
                       fdp.ConsumeBool() ? &hints : nullptr, &mNetContext, &result, &event);
}

}  // namespace

// Entry point of fuzzing test.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    [[maybe_unused]] static bool initialized = DoInit();
    // Sets delayQueries to let DnsTlsFrontend handle 2 queries at once.
    // If the Address Family is AF_UNSPEC, the frontend will receive both ipv4 and ipv6 queries.
    // Without setting delayQueries, the second query's connection between the dns_tls_frontend and
    // the fuzzing test may be closed and cause SSL_ERROR_SYSCALL. Then, the service will crash
    // after calling SSL_shutdown.
    // TODO: Make the test work without seeing delayQueries.
    dot.setDelayQueries(2);
    dot.setDelayQueriesTimeout(1000);
    FuzzedDataProvider fdp(data, size);

    // Chooses doh or dot.
    std::string flag = fdp.PickValueInArray({"0", "1"});
    ScopedSystemProperties sp(kDohFlag, flag);
    android::net::Experiments::getInstance()->update();

    auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
    // Chooses private DNS or not.
    if (fdp.ConsumeBool()) parcel.tlsServers = {};
    resolverCtrl.setResolverConfiguration(parcel);

    TestResolvGetaddrinfo(fdp);

    CleanUp();
    return 0;
}

}  // namespace android::net
+47 −0
Original line number Diff line number Diff line
#include "resolv_fuzzer_utils.h"

namespace android::net {
namespace {

// Tests resolv_gethostbyaddr.
void TestResolvGethostbyaddr(FuzzedDataProvider& fdp) {
    in6_addr v6addr;
    fdp.ConsumeBool() ? fdp.ConsumeData(&v6addr, sizeof(v6addr))    // Fuzzing data.
                      : inet_pton(AF_INET6, "::1.2.3.4", &v6addr);  // Correct data.
    // Fuzzs some values defined in nameser.h, e.g. NS_INADDRSZ.
    socklen_t mAddressLen = fdp.ConsumeIntegralInRange<int>(0, NS_IN6ADDRSZ + 1);
    // All valid address families in socket.h, e.g. AF_INET.
    int af = fdp.ConsumeIntegralInRange<int>(0, AF_MAX);
    hostent hbuf;
    char tmpbuf[MAXPACKET];
    hostent* hp;
    NetworkDnsEventReported event;

    resolv_gethostbyaddr(&v6addr, mAddressLen, af, &hbuf, tmpbuf, sizeof(tmpbuf), &mNetContext, &hp,
                         &event);
}

}  // namespace

// Entry point of fuzzing test.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    [[maybe_unused]] static bool initialized = DoInit();
    FuzzedDataProvider fdp(data, size);

    // Chooses doh or dot.
    std::string flag = fdp.PickValueInArray({"0", "1"});
    ScopedSystemProperties sp(kDohFlag, flag);
    android::net::Experiments::getInstance()->update();

    auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
    // Chooses private DNS or not.
    if (fdp.ConsumeBool()) parcel.tlsServers = {};
    resolverCtrl.setResolverConfiguration(parcel);

    TestResolvGethostbyaddr(fdp);

    CleanUp();
    return 0;
}

}  // namespace android::net
+43 −0
Original line number Diff line number Diff line
#include "resolv_fuzzer_utils.h"

namespace android::net {
namespace {

// Tests resolv_gethostbyname.
void TestResolvGethostbyname(FuzzedDataProvider& fdp) {
    std::string hostname = fdp.ConsumeRandomLengthString(MAXHOSTNAMELEN);
    // All valid address families in socket.h, e.g. AF_INET.
    int af = fdp.ConsumeIntegralInRange<int>(0, AF_MAX);
    hostent hbuf;
    char tmpbuf[MAXPACKET];
    hostent* hp;
    NetworkDnsEventReported event;

    resolv_gethostbyname(fdp.ConsumeBool() ? hostname.c_str() : nullptr, af, &hbuf, tmpbuf,
                         sizeof(tmpbuf), &mNetContext, &hp, &event);
}

}  // namespace

// Entry point of fuzzing test.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    [[maybe_unused]] static bool initialized = DoInit();
    FuzzedDataProvider fdp(data, size);

    // Chooses doh or dot.
    std::string flag = fdp.PickValueInArray({"0", "1"});
    ScopedSystemProperties sp(kDohFlag, flag);
    android::net::Experiments::getInstance()->update();

    auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
    // Chooses private DNS or not.
    if (fdp.ConsumeBool()) parcel.tlsServers = {};
    resolverCtrl.setResolverConfiguration(parcel);

    TestResolvGethostbyname(fdp);

    CleanUp();
    return 0;
}

}  // namespace android::net