Loading libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h +5 −1 Original line number Diff line number Diff line Loading @@ -19,10 +19,14 @@ #include <android-base/unique_fd.h> #include <fuzzer/FuzzedDataProvider.h> #include <vector> namespace android { // always valid or aborts // get a random FD for use in fuzzing, of a few different specific types base::unique_fd getRandomFd(FuzzedDataProvider* provider); // // may return multiple FDs (e.g. pipe), but will always return at least one std::vector<base::unique_fd> getRandomFds(FuzzedDataProvider* provider); } // namespace android libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h +4 −1 Original line number Diff line number Diff line Loading @@ -33,10 +33,13 @@ struct RandomParcelOptions { /** * Fill parcel data, including some random binder objects and FDs * * May insert additional FDs/binders if they own data related to the Parcel (e.g. the other * end of a pipe). * * p - the Parcel to fill * provider - takes ownership and completely consumes provider * writeHeader - optional function to write a specific header once the format of the parcel is * picked (for instance, to write an interface header) */ void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider, const RandomParcelOptions& = {}); void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider, RandomParcelOptions* options); } // namespace android libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ void fuzzService(const sp<IBinder>& binder, FuzzedDataProvider&& provider) { std::vector<uint8_t> subData = provider.ConsumeBytes<uint8_t>( provider.ConsumeIntegralInRange<size_t>(0, provider.remaining_bytes())); fillRandomParcel(&data, FuzzedDataProvider(subData.data(), subData.size()), options); fillRandomParcel(&data, FuzzedDataProvider(subData.data(), subData.size()), &options); Parcel reply; (void)target->transact(code, data, &reply, flags); Loading libs/binder/tests/parcel_fuzzer/main.cpp +19 −7 Original line number Diff line number Diff line Loading @@ -35,17 +35,22 @@ #include <sys/time.h> using android::fillRandomParcel; using android::RandomParcelOptions; using android::sp; using android::base::HexString; void fillRandomParcel(::android::hardware::Parcel* p, FuzzedDataProvider&& provider) { void fillRandomParcel(::android::hardware::Parcel* p, FuzzedDataProvider&& provider, RandomParcelOptions* options) { // TODO: functionality to create random parcels for libhwbinder parcels (void)options; std::vector<uint8_t> input = provider.ConsumeRemainingBytes<uint8_t>(); p->setData(input.data(), input.size()); } static void fillRandomParcel(NdkParcelAdapter* p, FuzzedDataProvider&& provider) { static void fillRandomParcel(NdkParcelAdapter* p, FuzzedDataProvider&& provider, RandomParcelOptions* options) { // fill underlying parcel using functions to fill random libbinder parcel fillRandomParcel(p->parcel(), std::move(provider)); fillRandomParcel(p->parcel(), std::move(provider), options); } template <typename P, typename B> Loading @@ -55,9 +60,11 @@ void doTransactFuzz(const char* backend, const sp<B>& binder, FuzzedDataProvider FUZZ_LOG() << "backend: " << backend; RandomParcelOptions options; P reply; P data; fillRandomParcel(&data, std::move(provider)); fillRandomParcel(&data, std::move(provider), &options); (void)binder->transact(code, data, &reply, flag); } Loading @@ -73,8 +80,10 @@ void doReadFuzz(const char* backend, const std::vector<ParcelRead<P>>& reads, std::vector<uint8_t> instructions = provider.ConsumeBytes<uint8_t>( provider.ConsumeIntegralInRange<size_t>(0, maxInstructions)); RandomParcelOptions options; P p; fillRandomParcel(&p, std::move(provider)); fillRandomParcel(&p, std::move(provider), &options); // since we are only using a byte to index CHECK(reads.size() <= 255) << reads.size(); Loading Loading @@ -103,9 +112,12 @@ void doAppendFuzz(const char* backend, FuzzedDataProvider&& provider) { std::vector<uint8_t> bytes = provider.ConsumeBytes<uint8_t>( provider.ConsumeIntegralInRange<size_t>(0, provider.remaining_bytes())); // same options so that FDs and binders could be shared in both Parcels RandomParcelOptions options; P p0, p1; fillRandomParcel(&p0, FuzzedDataProvider(bytes.data(), bytes.size())); fillRandomParcel(&p1, std::move(provider)); fillRandomParcel(&p0, FuzzedDataProvider(bytes.data(), bytes.size()), &options); fillRandomParcel(&p1, std::move(provider), &options); FUZZ_LOG() << "backend: " << backend; FUZZ_LOG() << "start: " << start << " len: " << len; Loading libs/binder/tests/parcel_fuzzer/random_fd.cpp +37 −6 Original line number Diff line number Diff line Loading @@ -23,13 +23,44 @@ namespace android { base::unique_fd getRandomFd(FuzzedDataProvider* provider) { int fd = provider->PickValueInArray<std::function<int()>>({ []() { return ashmem_create_region("binder test region", 1024); }, []() { return open("/dev/null", O_RDWR); }, using base::unique_fd; std::vector<unique_fd> getRandomFds(FuzzedDataProvider* provider) { std::vector<unique_fd> fds = provider->PickValueInArray< std::function<std::vector<unique_fd>()>>({ [&]() { std::vector<unique_fd> ret; ret.push_back(unique_fd( ashmem_create_region("binder test region", provider->ConsumeIntegralInRange<size_t>(0, 4096)))); return ret; }, [&]() { std::vector<unique_fd> ret; ret.push_back(unique_fd(open("/dev/null", O_RDWR))); return ret; }, [&]() { int pipefds[2]; int flags = O_CLOEXEC; if (provider->ConsumeBool()) flags |= O_DIRECT; if (provider->ConsumeBool()) flags |= O_NONBLOCK; CHECK_EQ(0, pipe2(pipefds, flags)); if (provider->ConsumeBool()) std::swap(pipefds[0], pipefds[1]); std::vector<unique_fd> ret; ret.push_back(unique_fd(pipefds[0])); ret.push_back(unique_fd(pipefds[1])); return ret; }, })(); CHECK(fd >= 0); return base::unique_fd(fd); for (const auto& fd : fds) CHECK(fd.ok()) << fd.get(); return fds; } } // namespace android Loading
libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h +5 −1 Original line number Diff line number Diff line Loading @@ -19,10 +19,14 @@ #include <android-base/unique_fd.h> #include <fuzzer/FuzzedDataProvider.h> #include <vector> namespace android { // always valid or aborts // get a random FD for use in fuzzing, of a few different specific types base::unique_fd getRandomFd(FuzzedDataProvider* provider); // // may return multiple FDs (e.g. pipe), but will always return at least one std::vector<base::unique_fd> getRandomFds(FuzzedDataProvider* provider); } // namespace android
libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h +4 −1 Original line number Diff line number Diff line Loading @@ -33,10 +33,13 @@ struct RandomParcelOptions { /** * Fill parcel data, including some random binder objects and FDs * * May insert additional FDs/binders if they own data related to the Parcel (e.g. the other * end of a pipe). * * p - the Parcel to fill * provider - takes ownership and completely consumes provider * writeHeader - optional function to write a specific header once the format of the parcel is * picked (for instance, to write an interface header) */ void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider, const RandomParcelOptions& = {}); void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider, RandomParcelOptions* options); } // namespace android
libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ void fuzzService(const sp<IBinder>& binder, FuzzedDataProvider&& provider) { std::vector<uint8_t> subData = provider.ConsumeBytes<uint8_t>( provider.ConsumeIntegralInRange<size_t>(0, provider.remaining_bytes())); fillRandomParcel(&data, FuzzedDataProvider(subData.data(), subData.size()), options); fillRandomParcel(&data, FuzzedDataProvider(subData.data(), subData.size()), &options); Parcel reply; (void)target->transact(code, data, &reply, flags); Loading
libs/binder/tests/parcel_fuzzer/main.cpp +19 −7 Original line number Diff line number Diff line Loading @@ -35,17 +35,22 @@ #include <sys/time.h> using android::fillRandomParcel; using android::RandomParcelOptions; using android::sp; using android::base::HexString; void fillRandomParcel(::android::hardware::Parcel* p, FuzzedDataProvider&& provider) { void fillRandomParcel(::android::hardware::Parcel* p, FuzzedDataProvider&& provider, RandomParcelOptions* options) { // TODO: functionality to create random parcels for libhwbinder parcels (void)options; std::vector<uint8_t> input = provider.ConsumeRemainingBytes<uint8_t>(); p->setData(input.data(), input.size()); } static void fillRandomParcel(NdkParcelAdapter* p, FuzzedDataProvider&& provider) { static void fillRandomParcel(NdkParcelAdapter* p, FuzzedDataProvider&& provider, RandomParcelOptions* options) { // fill underlying parcel using functions to fill random libbinder parcel fillRandomParcel(p->parcel(), std::move(provider)); fillRandomParcel(p->parcel(), std::move(provider), options); } template <typename P, typename B> Loading @@ -55,9 +60,11 @@ void doTransactFuzz(const char* backend, const sp<B>& binder, FuzzedDataProvider FUZZ_LOG() << "backend: " << backend; RandomParcelOptions options; P reply; P data; fillRandomParcel(&data, std::move(provider)); fillRandomParcel(&data, std::move(provider), &options); (void)binder->transact(code, data, &reply, flag); } Loading @@ -73,8 +80,10 @@ void doReadFuzz(const char* backend, const std::vector<ParcelRead<P>>& reads, std::vector<uint8_t> instructions = provider.ConsumeBytes<uint8_t>( provider.ConsumeIntegralInRange<size_t>(0, maxInstructions)); RandomParcelOptions options; P p; fillRandomParcel(&p, std::move(provider)); fillRandomParcel(&p, std::move(provider), &options); // since we are only using a byte to index CHECK(reads.size() <= 255) << reads.size(); Loading Loading @@ -103,9 +112,12 @@ void doAppendFuzz(const char* backend, FuzzedDataProvider&& provider) { std::vector<uint8_t> bytes = provider.ConsumeBytes<uint8_t>( provider.ConsumeIntegralInRange<size_t>(0, provider.remaining_bytes())); // same options so that FDs and binders could be shared in both Parcels RandomParcelOptions options; P p0, p1; fillRandomParcel(&p0, FuzzedDataProvider(bytes.data(), bytes.size())); fillRandomParcel(&p1, std::move(provider)); fillRandomParcel(&p0, FuzzedDataProvider(bytes.data(), bytes.size()), &options); fillRandomParcel(&p1, std::move(provider), &options); FUZZ_LOG() << "backend: " << backend; FUZZ_LOG() << "start: " << start << " len: " << len; Loading
libs/binder/tests/parcel_fuzzer/random_fd.cpp +37 −6 Original line number Diff line number Diff line Loading @@ -23,13 +23,44 @@ namespace android { base::unique_fd getRandomFd(FuzzedDataProvider* provider) { int fd = provider->PickValueInArray<std::function<int()>>({ []() { return ashmem_create_region("binder test region", 1024); }, []() { return open("/dev/null", O_RDWR); }, using base::unique_fd; std::vector<unique_fd> getRandomFds(FuzzedDataProvider* provider) { std::vector<unique_fd> fds = provider->PickValueInArray< std::function<std::vector<unique_fd>()>>({ [&]() { std::vector<unique_fd> ret; ret.push_back(unique_fd( ashmem_create_region("binder test region", provider->ConsumeIntegralInRange<size_t>(0, 4096)))); return ret; }, [&]() { std::vector<unique_fd> ret; ret.push_back(unique_fd(open("/dev/null", O_RDWR))); return ret; }, [&]() { int pipefds[2]; int flags = O_CLOEXEC; if (provider->ConsumeBool()) flags |= O_DIRECT; if (provider->ConsumeBool()) flags |= O_NONBLOCK; CHECK_EQ(0, pipe2(pipefds, flags)); if (provider->ConsumeBool()) std::swap(pipefds[0], pipefds[1]); std::vector<unique_fd> ret; ret.push_back(unique_fd(pipefds[0])); ret.push_back(unique_fd(pipefds[1])); return ret; }, })(); CHECK(fd >= 0); return base::unique_fd(fd); for (const auto& fd : fds) CHECK(fd.ok()) << fd.get(); return fds; } } // namespace android