Merge "binder_parcel_fuzzer: instrs w/ FuzzedDataProvider"
diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp
index 47ec776..7059d30 100644
--- a/libs/binder/tests/parcel_fuzzer/binder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder.cpp
@@ -73,20 +73,20 @@
uint8_t data[1337];
};
-#define PARCEL_READ_WITH_STATUS(T, FUN) \
- [] (const ::android::Parcel& p, uint8_t /*data*/) {\
- FUZZ_LOG() << "about to read " #T " using " #FUN " with status";\
- T t{};\
- status_t status = p.FUN(&t);\
- FUZZ_LOG() << #T " status: " << status /* << " value: " << t*/;\
+#define PARCEL_READ_WITH_STATUS(T, FUN) \
+ [](const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) { \
+ FUZZ_LOG() << "about to read " #T " using " #FUN " with status"; \
+ T t{}; \
+ status_t status = p.FUN(&t); \
+ FUZZ_LOG() << #T " status: " << status /* << " value: " << t*/; \
}
-#define PARCEL_READ_NO_STATUS(T, FUN) \
- [] (const ::android::Parcel& p, uint8_t /*data*/) {\
- FUZZ_LOG() << "about to read " #T " using " #FUN " with no status";\
- T t = p.FUN();\
- (void) t;\
- FUZZ_LOG() << #T " done " /* << " value: " << t*/;\
+#define PARCEL_READ_NO_STATUS(T, FUN) \
+ [](const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) { \
+ FUZZ_LOG() << "about to read " #T " using " #FUN " with no status"; \
+ T t = p.FUN(); \
+ (void)t; \
+ FUZZ_LOG() << #T " done " /* << " value: " << t*/; \
}
#define PARCEL_READ_OPT_STATUS(T, FUN) \
@@ -102,7 +102,9 @@
PARCEL_READ_NO_STATUS(size_t, dataPosition),
PARCEL_READ_NO_STATUS(size_t, dataCapacity),
PARCEL_READ_NO_STATUS(::android::binder::Status, enforceNoDataAvail),
- [] (const ::android::Parcel& p, uint8_t pos) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& provider) {
+ // aborts on larger values
+ size_t pos = provider.ConsumeIntegralInRange<size_t>(0, INT32_MAX);
FUZZ_LOG() << "about to setDataPosition: " << pos;
p.setDataPosition(pos);
FUZZ_LOG() << "setDataPosition done";
@@ -111,13 +113,13 @@
PARCEL_READ_NO_STATUS(size_t, hasFileDescriptors),
PARCEL_READ_NO_STATUS(std::vector<android::sp<android::IBinder>>, debugReadAllStrongBinders),
PARCEL_READ_NO_STATUS(std::vector<int>, debugReadAllFileDescriptors),
- [] (const ::android::Parcel& p, uint8_t len) {
- std::string interface(len, 'a');
+ [] (const ::android::Parcel& p, FuzzedDataProvider& provider) {
+ std::string interface = provider.ConsumeRandomLengthString();
FUZZ_LOG() << "about to enforceInterface: " << interface;
bool b = p.enforceInterface(::android::String16(interface.c_str()));
FUZZ_LOG() << "enforced interface: " << b;
},
- [] (const ::android::Parcel& p, uint8_t /*len*/) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to checkInterface";
android::sp<android::IBinder> aBinder = new android::BBinder();
bool b = p.checkInterface(aBinder.get());
@@ -125,13 +127,16 @@
},
PARCEL_READ_NO_STATUS(size_t, objectsCount),
PARCEL_READ_NO_STATUS(status_t, errorCheck),
- [] (const ::android::Parcel& p, uint8_t len) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& provider) {
+ // Read at least a bit. Unbounded allocation would OOM.
+ size_t len = provider.ConsumeIntegralInRange<size_t>(0, 1024);
FUZZ_LOG() << "about to read void*";
std::vector<uint8_t> data(len);
status_t status = p.read(data.data(), len);
FUZZ_LOG() << "read status: " << status;
},
- [] (const ::android::Parcel& p, uint8_t len) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& provider) {
+ size_t len = provider.ConsumeIntegral<size_t>();
FUZZ_LOG() << "about to readInplace";
const void* r = p.readInplace(len);
FUZZ_LOG() << "readInplace done. pointer: " << r << " bytes: " << (r ? HexString(r, len) : "null");
@@ -149,13 +154,13 @@
PARCEL_READ_WITH_STATUS(std::string, readUtf8FromUtf16),
PARCEL_READ_WITH_STATUS(std::unique_ptr<std::string>, readUtf8FromUtf16),
PARCEL_READ_WITH_STATUS(std::optional<std::string>, readUtf8FromUtf16),
- [] (const ::android::Parcel& p, uint8_t /*data*/) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to read c-str";
const char* str = p.readCString();
FUZZ_LOG() << "read c-str: " << (str ? str : "<empty string>");
},
PARCEL_READ_OPT_STATUS(android::String8, readString8),
- [] (const ::android::Parcel& p, uint8_t /*data*/) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to readString8Inplace";
size_t outLen = 0;
const char* str = p.readString8Inplace(&outLen);
@@ -165,7 +170,7 @@
PARCEL_READ_OPT_STATUS(android::String16, readString16),
PARCEL_READ_WITH_STATUS(std::unique_ptr<android::String16>, readString16),
PARCEL_READ_WITH_STATUS(std::optional<android::String16>, readString16),
- [] (const ::android::Parcel& p, uint8_t /*data*/) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to readString16Inplace";
size_t outLen = 0;
const char16_t* str = p.readString16Inplace(&outLen);
@@ -263,13 +268,13 @@
PARCEL_READ_WITH_STATUS(std::optional<std::array<std::array<std::optional<ExampleParcelable> COMMA 3> COMMA 4>>, readFixedArray),
#undef COMMA
- [] (const android::Parcel& p, uint8_t /*len*/) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to read flattenable";
ExampleFlattenable f;
status_t status = p.read(f);
FUZZ_LOG() << "read flattenable: " << status;
},
- [] (const android::Parcel& p, uint8_t /*len*/) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to read lite flattenable";
ExampleLightFlattenable f;
status_t status = p.read(f);
@@ -284,7 +289,7 @@
PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<BigStruct>>, resizeOutVector),
PARCEL_READ_NO_STATUS(int32_t, readExceptionCode),
- [] (const android::Parcel& p, uint8_t /*len*/) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to readNativeHandle";
native_handle_t* t = p.readNativeHandle();
FUZZ_LOG() << "readNativeHandle: " << t;
@@ -303,15 +308,16 @@
PARCEL_READ_WITH_STATUS(std::optional<std::vector<android::base::unique_fd>>, readUniqueFileDescriptorVector),
PARCEL_READ_WITH_STATUS(std::vector<android::base::unique_fd>, readUniqueFileDescriptorVector),
- [] (const android::Parcel& p, uint8_t len) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& provider) {
+ size_t len = provider.ConsumeIntegral<size_t>();
FUZZ_LOG() << "about to readBlob";
::android::Parcel::ReadableBlob blob;
status_t status = p.readBlob(len, &blob);
FUZZ_LOG() << "readBlob status: " << status;
},
- [] (const android::Parcel& p, uint8_t options) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& provider) {
FUZZ_LOG() << "about to readObject";
- bool nullMetaData = options & 0x1;
+ bool nullMetaData = provider.ConsumeBool();
const void* obj = static_cast<const void*>(p.readObject(nullMetaData));
FUZZ_LOG() << "readObject: " << obj;
},
@@ -319,20 +325,19 @@
PARCEL_READ_NO_STATUS(size_t, getOpenAshmemSize),
// additional parcelable objects defined in libbinder
- [] (const ::android::Parcel& p, uint8_t data) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& provider) {
using ::android::os::ParcelableHolder;
using ::android::Parcelable;
FUZZ_LOG() << "about to read ParcelableHolder using readParcelable with status";
- Parcelable::Stability stability = Parcelable::Stability::STABILITY_LOCAL;
- if ( (data & 1) == 1 ) {
- stability = Parcelable::Stability::STABILITY_VINTF;
- }
+ Parcelable::Stability stability = provider.ConsumeBool()
+ ? Parcelable::Stability::STABILITY_LOCAL
+ : Parcelable::Stability::STABILITY_VINTF;
ParcelableHolder t = ParcelableHolder(stability);
status_t status = p.readParcelable(&t);
FUZZ_LOG() << "ParcelableHolder status: " << status;
},
PARCEL_READ_WITH_STATUS(android::os::PersistableBundle, readParcelable),
- [] (const ::android::Parcel& p, uint8_t /* data */) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to call hasFileDescriptorsInRange() with status";
size_t offset = p.readUint32();
size_t length = p.readUint32();
@@ -340,7 +345,7 @@
status_t status = p.hasFileDescriptorsInRange(offset, length, &result);
FUZZ_LOG() << " status: " << status << " result: " << result;
},
- [] (const ::android::Parcel& p, uint8_t /* data */) {
+ [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to call compareDataInRange() with status";
size_t thisOffset = p.readUint32();
size_t otherOffset = p.readUint32();
diff --git a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
index 5aeb5cc..26d6770 100644
--- a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
@@ -70,7 +70,7 @@
}
#define PARCEL_READ(T, FUN) \
- [](const NdkParcelAdapter& p, uint8_t /*data*/) { \
+ [](const NdkParcelAdapter& p, FuzzedDataProvider& /*provider*/) { \
FUZZ_LOG() << "about to read " #T " using " #FUN " with status"; \
T t{}; \
binder_status_t status = FUN(p.aParcel(), &t); \
@@ -80,32 +80,37 @@
// clang-format off
std::vector<ParcelRead<NdkParcelAdapter>> BINDER_NDK_PARCEL_READ_FUNCTIONS{
// methods from binder_parcel.h
- [](const NdkParcelAdapter& p, uint8_t pos) {
+ [](const NdkParcelAdapter& p, FuzzedDataProvider& provider) {
+ // aborts on larger values
+ size_t pos = provider.ConsumeIntegralInRange<size_t>(0, INT32_MAX);
FUZZ_LOG() << "about to set data position to " << pos;
binder_status_t status = AParcel_setDataPosition(p.aParcel(), pos);
FUZZ_LOG() << "set data position: " << status;
},
- [](const NdkParcelAdapter& p, uint8_t /*data*/) {
+ [](const NdkParcelAdapter& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to read status header";
ndk::ScopedAStatus t;
binder_status_t status = AParcel_readStatusHeader(p.aParcel(), t.getR());
FUZZ_LOG() << "read status header: " << status;
},
- [](const NdkParcelAdapter& p, uint8_t /*data*/) {
+ [](const NdkParcelAdapter& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to getDataSize the parcel";
AParcel_getDataSize(p.aParcel());
FUZZ_LOG() << "getDataSize done";
},
- [](const NdkParcelAdapter& p, uint8_t data) {
+ [](const NdkParcelAdapter& p, FuzzedDataProvider& provider) {
FUZZ_LOG() << "about to read a ParcelableHolder";
- ndk::AParcelableHolder ph {(data % 2 == 1) ? ndk::STABILITY_LOCAL : ndk::STABILITY_VINTF};
+ ndk::AParcelableHolder ph {provider.ConsumeBool() ? ndk::STABILITY_LOCAL : ndk::STABILITY_VINTF};
binder_status_t status = AParcel_readParcelable(p.aParcel(), &ph);
FUZZ_LOG() << "read the ParcelableHolder: " << status;
},
- [](const NdkParcelAdapter& p, uint8_t data) {
- FUZZ_LOG() << "about to appendFrom";
+ [](const NdkParcelAdapter& p, FuzzedDataProvider& provider) {
+ size_t offset = provider.ConsumeIntegral<size_t>();
+ size_t pos = provider.ConsumeIntegral<size_t>();
+ FUZZ_LOG() << "about to appendFrom " << pos;
+ // TODO: create random parcel
AParcel* parcel = AParcel_create();
- binder_status_t status = AParcel_appendFrom(p.aParcel(), parcel, 0, data);
+ binder_status_t status = AParcel_appendFrom(p.aParcel(), parcel, offset, pos);
AParcel_delete(parcel);
FUZZ_LOG() << "appendFrom: " << status;
},
diff --git a/libs/binder/tests/parcel_fuzzer/hwbinder.cpp b/libs/binder/tests/parcel_fuzzer/hwbinder.cpp
index ee9840f..438e8ae 100644
--- a/libs/binder/tests/parcel_fuzzer/hwbinder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/hwbinder.cpp
@@ -35,19 +35,19 @@
#define PARCEL_READ_OPT_STATUS(T, FUN) \
PARCEL_READ_NO_STATUS(T, FUN), PARCEL_READ_WITH_STATUS(T, FUN)
-#define PARCEL_READ_NO_STATUS(T, FUN) \
- [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {\
- FUZZ_LOG() << "about to read " #T " using " #FUN " with no status";\
- T t = p.FUN();\
- FUZZ_LOG() << #T " value: " << t;\
+#define PARCEL_READ_NO_STATUS(T, FUN) \
+ [](const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) { \
+ FUZZ_LOG() << "about to read " #T " using " #FUN " with no status"; \
+ T t = p.FUN(); \
+ FUZZ_LOG() << #T " value: " << t; \
}
-#define PARCEL_READ_WITH_STATUS(T, FUN) \
- [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {\
- FUZZ_LOG() << "about to read " #T " using " #FUN " with status";\
- T t;\
- status_t status = p.FUN(&t);\
- FUZZ_LOG() << #T " status: " << status << " value: " << t;\
+#define PARCEL_READ_WITH_STATUS(T, FUN) \
+ [](const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) { \
+ FUZZ_LOG() << "about to read " #T " using " #FUN " with status"; \
+ T t; \
+ status_t status = p.FUN(&t); \
+ FUZZ_LOG() << #T " status: " << status << " value: " << t; \
}
// clang-format off
@@ -56,27 +56,30 @@
PARCEL_READ_NO_STATUS(size_t, dataAvail),
PARCEL_READ_NO_STATUS(size_t, dataPosition),
PARCEL_READ_NO_STATUS(size_t, dataCapacity),
- [] (const ::android::hardware::Parcel& p, uint8_t pos) {
+ [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
+ // aborts on larger values
+ size_t pos = provider.ConsumeIntegralInRange<size_t>(0, INT32_MAX);
FUZZ_LOG() << "about to setDataPosition: " << pos;
p.setDataPosition(pos);
FUZZ_LOG() << "setDataPosition done";
},
- [] (const ::android::hardware::Parcel& p, uint8_t length) {
+ [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
FUZZ_LOG() << "about to enforceInterface";
- std::string interfaceName(length, 'a');
- bool okay = p.enforceInterface(interfaceName.c_str());
+ bool okay = p.enforceInterface(provider.ConsumeRandomLengthString().c_str());
FUZZ_LOG() << "enforceInterface status: " << okay;
},
PARCEL_READ_NO_STATUS(size_t, objectsCount),
- [] (const ::android::hardware::Parcel& p, uint8_t length) {
+ [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
+ // Read at least a bit. Unbounded allocation would OOM.
+ size_t length = provider.ConsumeIntegralInRange<size_t>(0, 1024);
FUZZ_LOG() << "about to read";
std::vector<uint8_t> data (length);
status_t status = p.read(data.data(), length);
FUZZ_LOG() << "read status: " << status << " data: " << HexString(data.data(), data.size());
},
- [] (const ::android::hardware::Parcel& p, uint8_t length) {
+ [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
+ size_t length = provider.ConsumeIntegral<size_t>();
FUZZ_LOG() << "about to read";
- std::vector<uint8_t> data (length);
const void* inplace = p.readInplace(length);
FUZZ_LOG() << "read status: " << (inplace ? HexString(inplace, length) : "null");
},
@@ -91,14 +94,14 @@
PARCEL_READ_OPT_STATUS(float, readFloat),
PARCEL_READ_OPT_STATUS(double, readDouble),
PARCEL_READ_OPT_STATUS(bool, readBool),
- [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
+ [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to readCString";
const char* str = p.readCString();
FUZZ_LOG() << "readCString " << (str ? str : "<null>");
},
PARCEL_READ_OPT_STATUS(::android::String16, readString16),
PARCEL_READ_WITH_STATUS(std::unique_ptr<::android::String16>, readString16),
- [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
+ [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to readString16Inplace";
size_t outSize = 0;
const char16_t* str = p.readString16Inplace(&outSize);
@@ -106,7 +109,8 @@
},
PARCEL_READ_OPT_STATUS(::android::sp<::android::hardware::IBinder>, readStrongBinder),
PARCEL_READ_WITH_STATUS(::android::sp<::android::hardware::IBinder>, readNullableStrongBinder),
- [] (const ::android::hardware::Parcel& p, uint8_t size) {
+ [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
+ size_t size = provider.ConsumeIntegral<size_t>();
FUZZ_LOG() << "about to readBuffer";
size_t handle = 0;
const void* data = nullptr;
@@ -116,7 +120,8 @@
// should be null since we don't create any IPC objects
CHECK(data == nullptr) << data;
},
- [] (const ::android::hardware::Parcel& p, uint8_t size) {
+ [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
+ size_t size = provider.ConsumeIntegral<size_t>();
FUZZ_LOG() << "about to readNullableBuffer";
size_t handle = 0;
const void* data = nullptr;
@@ -126,7 +131,8 @@
// should be null since we don't create any IPC objects
CHECK(data == nullptr) << data;
},
- [] (const ::android::hardware::Parcel& p, uint8_t size) {
+ [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
+ size_t size = provider.ConsumeIntegral<size_t>();
FUZZ_LOG() << "about to readEmbeddedBuffer";
size_t handle = 0;
size_t parent_buffer_handle = 0;
@@ -138,7 +144,8 @@
// should be null since we don't create any IPC objects
CHECK(data == nullptr) << data;
},
- [] (const ::android::hardware::Parcel& p, uint8_t size) {
+ [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
+ size_t size = provider.ConsumeIntegral<size_t>();
FUZZ_LOG() << "about to readNullableEmbeddedBuffer";
size_t handle = 0;
size_t parent_buffer_handle = 0;
@@ -150,7 +157,7 @@
// should be null since we don't create any IPC objects
CHECK(data == nullptr) << data;
},
- [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
+ [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to readNativeHandleNoDup";
const native_handle_t* handle = nullptr;
status_t status = p.readNativeHandleNoDup(&handle);
diff --git a/libs/binder/tests/parcel_fuzzer/main.cpp b/libs/binder/tests/parcel_fuzzer/main.cpp
index f435dae..70c32cb 100644
--- a/libs/binder/tests/parcel_fuzzer/main.cpp
+++ b/libs/binder/tests/parcel_fuzzer/main.cpp
@@ -83,19 +83,14 @@
FUZZ_LOG() << "input: " << HexString(p.data(), p.dataSize());
FUZZ_LOG() << "instructions: " << HexString(instructions.data(), instructions.size());
- for (size_t i = 0; i + 1 < instructions.size(); i += 2) {
- uint8_t a = instructions[i];
- uint8_t readIdx = a % reads.size();
+ FuzzedDataProvider instructionsProvider(instructions.data(), instructions.size());
+ while (instructionsProvider.remaining_bytes() > 0) {
+ uint8_t idx = instructionsProvider.ConsumeIntegralInRange<uint8_t>(0, reads.size() - 1);
- uint8_t b = instructions[i + 1];
+ FUZZ_LOG() << "Instruction " << idx << " avail: " << p.dataAvail()
+ << " pos: " << p.dataPosition() << " cap: " << p.dataCapacity();
- FUZZ_LOG() << "Instruction: " << (i / 2) + 1 << "/" << instructions.size() / 2
- << " cmd: " << static_cast<size_t>(a) << " (" << static_cast<size_t>(readIdx)
- << ") arg: " << static_cast<size_t>(b) << " size: " << p.dataSize()
- << " avail: " << p.dataAvail() << " pos: " << p.dataPosition()
- << " cap: " << p.dataCapacity();
-
- reads[readIdx](p, b);
+ reads[idx](p, instructionsProvider);
}
}
diff --git a/libs/binder/tests/parcel_fuzzer/parcel_fuzzer.h b/libs/binder/tests/parcel_fuzzer/parcel_fuzzer.h
index b68a8a9..765a93e 100644
--- a/libs/binder/tests/parcel_fuzzer/parcel_fuzzer.h
+++ b/libs/binder/tests/parcel_fuzzer/parcel_fuzzer.h
@@ -15,5 +15,9 @@
*/
#pragma once
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <functional>
+
template <typename P>
-using ParcelRead = std::function<void(const P& p, uint8_t data)>;
+using ParcelRead = std::function<void(const P& p, FuzzedDataProvider& provider)>;