summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Steven Moreland <smoreland@google.com> 2022-03-16 01:03:02 +0000
committer Steven Moreland <smoreland@google.com> 2022-03-16 01:05:44 +0000
commit9711ad3d0e9792eb7073cc8525eaaefe49285b9c (patch)
treefef24e9b39b89c7ceefa3dd6738a4ee21fa56af3
parent8a2607c4aa1519e68f2e99529d6f5036a5b2c5dc (diff)
libbinder_random_parcel: driver writes iface token
It's really hard for the fuzzer to guess the interface token, so rather than generating corpus or dictionaries for these for every fuzzer, have the driver do this. As a follow-up, we should have the driver keep track of binder objects which are returned inside of the reply Parcel and also fuzz these objects as well as send them back into the service. Bug: 224646709 Test: vibrator example fuzzer instantly hits code inside of the vibrator service when fuzzing. Change-Id: Idf1970439b87a01b44df1904605858c98a49e81a
-rw-r--r--libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h11
-rw-r--r--libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp9
-rw-r--r--libs/binder/tests/parcel_fuzzer/random_parcel.cpp8
3 files changed, 25 insertions, 3 deletions
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 db35e39108..633626ca44 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
@@ -19,9 +19,18 @@
#include <binder/Parcel.h>
#include <fuzzer/FuzzedDataProvider.h>
+#include <functional>
+
namespace android {
/**
* Fill parcel data, including some random binder objects and FDs
+ *
+ * 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);
+void fillRandomParcel(
+ Parcel* p, FuzzedDataProvider&& provider,
+ std::function<void(Parcel* p, FuzzedDataProvider& provider)> writeHeader = nullptr);
} // namespace android
diff --git a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
index e849c9bbce..be39bb9195 100644
--- a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
+++ b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
@@ -27,7 +27,14 @@ 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()));
+ fillRandomParcel(&data, FuzzedDataProvider(subData.data(), subData.size()),
+ [&binder](Parcel* p, FuzzedDataProvider& provider) {
+ // most code will be behind checks that the head of the Parcel
+ // is exactly this, so make it easier for fuzzers to reach this
+ if (provider.ConsumeBool()) {
+ p->writeInterfaceToken(binder->getInterfaceDescriptor());
+ }
+ });
Parcel reply;
(void)binder->transact(code, data, &reply, flags);
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
index 89eadae981..cfabc1e6b5 100644
--- a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
@@ -39,15 +39,21 @@ static void fillRandomParcelData(Parcel* p, FuzzedDataProvider&& provider) {
CHECK(OK == p->write(data.data(), data.size()));
}
-void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider) {
+void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider,
+ std::function<void(Parcel* p, FuzzedDataProvider& provider)> writeHeader) {
if (provider.ConsumeBool()) {
auto session = RpcSession::make(RpcTransportCtxFactoryRaw::make());
CHECK_EQ(OK, session->addNullDebuggingClient());
p->markForRpc(session);
+
+ writeHeader(p, provider);
+
fillRandomParcelData(p, std::move(provider));
return;
}
+ writeHeader(p, provider);
+
while (provider.remaining_bytes() > 0) {
auto fillFunc = provider.PickValueInArray<const std::function<void()>>({
// write data