diff options
author | 2021-09-13 11:31:51 -0700 | |
---|---|---|
committer | 2021-09-13 16:41:13 -0700 | |
commit | 728587b2851fa5aab102a16d55048a8deb23f18e (patch) | |
tree | 86bb35e298749ae4ec88da6526a607497d905a0c | |
parent | 791e466ea0b4283b53cf41ef9dfa37118b345df4 (diff) |
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
-rw-r--r-- | libs/binder/tests/unit_fuzzers/Android.bp | 1 | ||||
-rw-r--r-- | libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp | 47 | ||||
-rw-r--r-- | libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h | 6 |
3 files changed, 42 insertions, 12 deletions
diff --git a/libs/binder/tests/unit_fuzzers/Android.bp b/libs/binder/tests/unit_fuzzers/Android.bp index b1263e8d8e..6f054d2284 100644 --- a/libs/binder/tests/unit_fuzzers/Android.bp +++ b/libs/binder/tests/unit_fuzzers/Android.bp @@ -51,7 +51,6 @@ cc_fuzz { cc_fuzz { name: "binder_bpBinderFuzz", defaults: ["binder_fuzz_defaults"], - host_supported: false, srcs: ["BpBinderFuzz.cpp"], } diff --git a/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp b/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp index c50279b13d..95582bf0d4 100644 --- a/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp +++ b/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp @@ -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 diff --git a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h index 6ca0e2f075..741987f754 100644 --- a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h +++ b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h @@ -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>(); |