Merge "fuzzer driver: more fd types" am: 97fc22896e am: 202d7a1974 am: 1fe2ef49ca am: 81862367a0 am: 28ae4e8753
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2154180
Change-Id: Ib4cada44c818550a3e7154c3e8e1e4ed90afdbaf
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h
index 843b6e3..6ea9708 100644
--- a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h
+++ b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h
@@ -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
diff --git a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
index 459fb12..27587a9 100644
--- a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
+++ b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
@@ -33,10 +33,13 @@
/**
* 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
diff --git a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
index d5aa353..32494e3 100644
--- a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
+++ b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
@@ -44,7 +44,7 @@
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);
diff --git a/libs/binder/tests/parcel_fuzzer/main.cpp b/libs/binder/tests/parcel_fuzzer/main.cpp
index 180a177..bef4ab6 100644
--- a/libs/binder/tests/parcel_fuzzer/main.cpp
+++ b/libs/binder/tests/parcel_fuzzer/main.cpp
@@ -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>
@@ -55,9 +60,11 @@
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);
}
@@ -73,8 +80,10 @@
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();
@@ -103,9 +112,12 @@
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;
diff --git a/libs/binder/tests/parcel_fuzzer/random_fd.cpp b/libs/binder/tests/parcel_fuzzer/random_fd.cpp
index ab0b7e3..3fcf104 100644
--- a/libs/binder/tests/parcel_fuzzer/random_fd.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_fd.cpp
@@ -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
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
index 0204f5e..51cb768 100644
--- a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
@@ -39,23 +39,24 @@
CHECK(OK == p->write(data.data(), data.size()));
}
-void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider,
- const RandomParcelOptions& options) {
+void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider, RandomParcelOptions* options) {
+ CHECK_NE(options, nullptr);
+
if (provider.ConsumeBool()) {
auto session = RpcSession::make(RpcTransportCtxFactoryRaw::make());
CHECK_EQ(OK, session->addNullDebuggingClient());
p->markForRpc(session);
- if (options.writeHeader) {
- options.writeHeader(p, provider);
+ if (options->writeHeader) {
+ options->writeHeader(p, provider);
}
fillRandomParcelData(p, std::move(provider));
return;
}
- if (options.writeHeader) {
- options.writeHeader(p, provider);
+ if (options->writeHeader) {
+ options->writeHeader(p, provider);
}
while (provider.remaining_bytes() > 0) {
@@ -69,15 +70,21 @@
},
// write FD
[&]() {
- if (options.extraFds.size() > 0 && provider.ConsumeBool()) {
- const base::unique_fd& fd = options.extraFds.at(
+ if (options->extraFds.size() > 0 && provider.ConsumeBool()) {
+ const base::unique_fd& fd = options->extraFds.at(
provider.ConsumeIntegralInRange<size_t>(0,
- options.extraFds.size() -
+ options->extraFds.size() -
1));
CHECK(OK == p->writeFileDescriptor(fd.get(), false /*takeOwnership*/));
} else {
- base::unique_fd fd = getRandomFd(&provider);
- CHECK(OK == p->writeFileDescriptor(fd.release(), true /*takeOwnership*/));
+ std::vector<base::unique_fd> fds = getRandomFds(&provider);
+ CHECK(OK ==
+ p->writeFileDescriptor(fds.begin()->release(),
+ true /*takeOwnership*/));
+
+ options->extraFds.insert(options->extraFds.end(),
+ std::make_move_iterator(fds.begin() + 1),
+ std::make_move_iterator(fds.end()));
}
},
// write binder
@@ -98,10 +105,10 @@
return IInterface::asBinder(defaultServiceManager());
},
[&]() -> sp<IBinder> {
- if (options.extraBinders.size() > 0 && provider.ConsumeBool()) {
- return options.extraBinders.at(
+ if (options->extraBinders.size() > 0 && provider.ConsumeBool()) {
+ return options->extraBinders.at(
provider.ConsumeIntegralInRange<
- size_t>(0, options.extraBinders.size() - 1));
+ size_t>(0, options->extraBinders.size() - 1));
} else {
return nullptr;
}