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

Commit 728587b2 authored by Steven Moreland's avatar Steven Moreland
Browse files

binder_bpBinderFuzz: use valid BpBinder object

Using RPC binder to work on host. Avoid using BpBinder::create which
will become private.

Bug: 167966510
Test: binder_bpBinderFuzz
Change-Id: Icfb454c25ceec8ca9dd47d78d0b81642dc7823f0
parent 791e466e
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -51,7 +51,6 @@ cc_fuzz {
cc_fuzz {
    name: "binder_bpBinderFuzz",
    defaults: ["binder_fuzz_defaults"],
    host_supported: false,
    srcs: ["BpBinderFuzz.cpp"],
}

+38 −9
Original line number Diff line number Diff line
@@ -19,8 +19,15 @@
#include <commonFuzzHelpers.h>
#include <fuzzer/FuzzedDataProvider.h>

#include <android-base/logging.h>
#include <binder/BpBinder.h>
#include <binder/IServiceManager.h>
#include <binder/RpcServer.h>
#include <binder/RpcSession.h>

#include <signal.h>
#include <sys/prctl.h>
#include <thread>

namespace android {

@@ -28,13 +35,31 @@ namespace android {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    FuzzedDataProvider fdp(data, size);

    // TODO: In the future it would be more effective to fork a new process and then pass a BBinder
    // to your process. Right now this is not implemented because it would involved fuzzing IPC on a
    // forked process, and libfuzzer will not be able to handle code coverage. This would lead to
    // crashes that are not easy to diagnose.
    int32_t handle = fdp.ConsumeIntegralInRange<int32_t>(0, 1024);
    sp<BpBinder> bpbinder = BpBinder::create(handle);
    if (bpbinder == nullptr) return 0;
    std::string addr = std::string(getenv("TMPDIR") ?: "/tmp") + "/binderRpcBenchmark";
    (void)unlink(addr.c_str());

    sp<RpcServer> server = RpcServer::make();

    // use RPC binder because fuzzer can't get coverage from another process.
    auto thread = std::thread([&]() {
        prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
        server->setRootObject(sp<BBinder>::make());
        server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
        CHECK_EQ(OK, server->setupUnixDomainServer(addr.c_str()));
        server->join();
    });

    sp<RpcSession> session = RpcSession::make();
    status_t status;
    for (size_t tries = 0; tries < 5; tries++) {
        usleep(10000);
        status = session->setupUnixDomainClient(addr.c_str());
        if (status == OK) goto success;
    }
    LOG(FATAL) << "Unable to connect";
success:

    sp<BpBinder> bpBinder = session->getRootObject()->remoteBinder();

    // To prevent memory from running out from calling too many add item operations.
    const uint32_t MAX_RUNS = 2048;
@@ -43,12 +68,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {

    while (fdp.remaining_bytes() > 0 && count++ < MAX_RUNS) {
        if (fdp.ConsumeBool()) {
            callArbitraryFunction(&fdp, gBPBinderOperations, bpbinder, s_recipient);
            callArbitraryFunction(&fdp, gBPBinderOperations, bpBinder, s_recipient);
        } else {
            callArbitraryFunction(&fdp, gIBinderOperations, bpbinder.get());
            callArbitraryFunction(&fdp, gIBinderOperations, bpBinder.get());
        }
    }

    CHECK(session->shutdownAndWait(true)) << "couldn't shutdown session";
    CHECK(server->shutdown()) << "couldn't shutdown server";
    thread.join();

    return 0;
}
} // namespace android
+4 −2
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ static const std::vector<std::function<void(FuzzedDataProvider*, const sp<BpBind
                    const sp<IBinder::DeathRecipient>& s_recipient) -> void {
                     // Clean up possible leftover memory.
                     wp<IBinder::DeathRecipient> outRecipient(nullptr);
                     bpbinder->sendObituary();
                     if (!bpbinder->isRpcBinder()) bpbinder->sendObituary();
                     bpbinder->unlinkToDeath(nullptr, reinterpret_cast<void*>(&kBpBinderCookie), 0,
                                             &outRecipient);

@@ -72,7 +72,9 @@ static const std::vector<std::function<void(FuzzedDataProvider*, const sp<BpBind
                 [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder,
                    const sp<IBinder::DeathRecipient>&) -> void { bpbinder->remoteBinder(); },
                 [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder,
                    const sp<IBinder::DeathRecipient>&) -> void { bpbinder->sendObituary(); },
                    const sp<IBinder::DeathRecipient>&) -> void {
                     if (!bpbinder->isRpcBinder()) bpbinder->sendObituary();
                 },
                 [](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder,
                    const sp<IBinder::DeathRecipient>&) -> void {
                     uint32_t uid = fdp->ConsumeIntegral<uint32_t>();