Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb4f247c authored by Steven Moreland's avatar Steven Moreland
Browse files

binder_parcel_fuzzer: instrs w/ FuzzedDataProvider

Use FuzzedDataProvider to process instructions to various functions.
Before, we had one byte of data to go with each function. This makes
more efficient use of input data when we don't need that extra
information, and in other cases, it gives us options to
do more complicated things with more than a byte of data. As a result,
this test now covers more state space.

Bug: 202528015
Test: binder_parcel_fuzzer
Change-Id: I5942ce78631f7f4fe1e401b6c50210747f9c80a4
parent 97c1356a
Loading
Loading
Loading
Loading
+39 −34
Original line number Original line Diff line number Diff line
@@ -74,7 +74,7 @@ struct BigStruct {
};
};


#define PARCEL_READ_WITH_STATUS(T, FUN)                                  \
#define PARCEL_READ_WITH_STATUS(T, FUN)                                  \
    [] (const ::android::Parcel& p, uint8_t /*data*/) {\
    [](const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {   \
        FUZZ_LOG() << "about to read " #T " using " #FUN " with status"; \
        FUZZ_LOG() << "about to read " #T " using " #FUN " with status"; \
        T t{};                                                           \
        T t{};                                                           \
        status_t status = p.FUN(&t);                                     \
        status_t status = p.FUN(&t);                                     \
@@ -82,7 +82,7 @@ struct BigStruct {
    }
    }


#define PARCEL_READ_NO_STATUS(T, FUN)                                       \
#define PARCEL_READ_NO_STATUS(T, FUN)                                       \
    [] (const ::android::Parcel& p, uint8_t /*data*/) {\
    [](const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {      \
        FUZZ_LOG() << "about to read " #T " using " #FUN " with no status"; \
        FUZZ_LOG() << "about to read " #T " using " #FUN " with no status"; \
        T t = p.FUN();                                                      \
        T t = p.FUN();                                                      \
        (void)t;                                                            \
        (void)t;                                                            \
@@ -102,7 +102,9 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    PARCEL_READ_NO_STATUS(size_t, dataPosition),
    PARCEL_READ_NO_STATUS(size_t, dataPosition),
    PARCEL_READ_NO_STATUS(size_t, dataCapacity),
    PARCEL_READ_NO_STATUS(size_t, dataCapacity),
    PARCEL_READ_NO_STATUS(::android::binder::Status, enforceNoDataAvail),
    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;
        FUZZ_LOG() << "about to setDataPosition: " << pos;
        p.setDataPosition(pos);
        p.setDataPosition(pos);
        FUZZ_LOG() << "setDataPosition done";
        FUZZ_LOG() << "setDataPosition done";
@@ -111,13 +113,13 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    PARCEL_READ_NO_STATUS(size_t, hasFileDescriptors),
    PARCEL_READ_NO_STATUS(size_t, hasFileDescriptors),
    PARCEL_READ_NO_STATUS(std::vector<android::sp<android::IBinder>>, debugReadAllStrongBinders),
    PARCEL_READ_NO_STATUS(std::vector<android::sp<android::IBinder>>, debugReadAllStrongBinders),
    PARCEL_READ_NO_STATUS(std::vector<int>, debugReadAllFileDescriptors),
    PARCEL_READ_NO_STATUS(std::vector<int>, debugReadAllFileDescriptors),
    [] (const ::android::Parcel& p, uint8_t len) {
    [] (const ::android::Parcel& p, FuzzedDataProvider& provider) {
        std::string interface(len, 'a');
        std::string interface = provider.ConsumeRandomLengthString();
        FUZZ_LOG() << "about to enforceInterface: " << interface;
        FUZZ_LOG() << "about to enforceInterface: " << interface;
        bool b = p.enforceInterface(::android::String16(interface.c_str()));
        bool b = p.enforceInterface(::android::String16(interface.c_str()));
        FUZZ_LOG() << "enforced interface: " << b;
        FUZZ_LOG() << "enforced interface: " << b;
    },
    },
    [] (const ::android::Parcel& p, uint8_t /*len*/) {
    [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
        FUZZ_LOG() << "about to checkInterface";
        FUZZ_LOG() << "about to checkInterface";
        android::sp<android::IBinder> aBinder = new android::BBinder();
        android::sp<android::IBinder> aBinder = new android::BBinder();
        bool b = p.checkInterface(aBinder.get());
        bool b = p.checkInterface(aBinder.get());
@@ -125,13 +127,16 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    },
    },
    PARCEL_READ_NO_STATUS(size_t, objectsCount),
    PARCEL_READ_NO_STATUS(size_t, objectsCount),
    PARCEL_READ_NO_STATUS(status_t, errorCheck),
    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*";
        FUZZ_LOG() << "about to read void*";
        std::vector<uint8_t> data(len);
        std::vector<uint8_t> data(len);
        status_t status = p.read(data.data(), len);
        status_t status = p.read(data.data(), len);
        FUZZ_LOG() << "read status: " << status;
        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";
        FUZZ_LOG() << "about to readInplace";
        const void* r = p.readInplace(len);
        const void* r = p.readInplace(len);
        FUZZ_LOG() << "readInplace done. pointer: " << r << " bytes: " << (r ? HexString(r, len) : "null");
        FUZZ_LOG() << "readInplace done. pointer: " << r << " bytes: " << (r ? HexString(r, len) : "null");
@@ -149,13 +154,13 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    PARCEL_READ_WITH_STATUS(std::string, readUtf8FromUtf16),
    PARCEL_READ_WITH_STATUS(std::string, readUtf8FromUtf16),
    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::string>, readUtf8FromUtf16),
    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::string>, readUtf8FromUtf16),
    PARCEL_READ_WITH_STATUS(std::optional<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";
        FUZZ_LOG() << "about to read c-str";
        const char* str = p.readCString();
        const char* str = p.readCString();
        FUZZ_LOG() << "read c-str: " << (str ? str : "<empty string>");
        FUZZ_LOG() << "read c-str: " << (str ? str : "<empty string>");
    },
    },
    PARCEL_READ_OPT_STATUS(android::String8, readString8),
    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";
        FUZZ_LOG() << "about to readString8Inplace";
        size_t outLen = 0;
        size_t outLen = 0;
        const char* str = p.readString8Inplace(&outLen);
        const char* str = p.readString8Inplace(&outLen);
@@ -165,7 +170,7 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    PARCEL_READ_OPT_STATUS(android::String16, readString16),
    PARCEL_READ_OPT_STATUS(android::String16, readString16),
    PARCEL_READ_WITH_STATUS(std::unique_ptr<android::String16>, readString16),
    PARCEL_READ_WITH_STATUS(std::unique_ptr<android::String16>, readString16),
    PARCEL_READ_WITH_STATUS(std::optional<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";
        FUZZ_LOG() << "about to readString16Inplace";
        size_t outLen = 0;
        size_t outLen = 0;
        const char16_t* str = p.readString16Inplace(&outLen);
        const char16_t* str = p.readString16Inplace(&outLen);
@@ -263,13 +268,13 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    PARCEL_READ_WITH_STATUS(std::optional<std::array<std::array<std::optional<ExampleParcelable> COMMA 3> COMMA 4>>, readFixedArray),
    PARCEL_READ_WITH_STATUS(std::optional<std::array<std::array<std::optional<ExampleParcelable> COMMA 3> COMMA 4>>, readFixedArray),
#undef COMMA
#undef COMMA


    [] (const android::Parcel& p, uint8_t /*len*/) {
    [] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
        FUZZ_LOG() << "about to read flattenable";
        FUZZ_LOG() << "about to read flattenable";
        ExampleFlattenable f;
        ExampleFlattenable f;
        status_t status = p.read(f);
        status_t status = p.read(f);
        FUZZ_LOG() << "read flattenable: " << status;
        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";
        FUZZ_LOG() << "about to read lite flattenable";
        ExampleLightFlattenable f;
        ExampleLightFlattenable f;
        status_t status = p.read(f);
        status_t status = p.read(f);
@@ -284,7 +289,7 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<BigStruct>>, resizeOutVector),
    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<BigStruct>>, resizeOutVector),


    PARCEL_READ_NO_STATUS(int32_t, readExceptionCode),
    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";
        FUZZ_LOG() << "about to readNativeHandle";
        native_handle_t* t = p.readNativeHandle();
        native_handle_t* t = p.readNativeHandle();
        FUZZ_LOG() << "readNativeHandle: " << t;
        FUZZ_LOG() << "readNativeHandle: " << t;
@@ -303,15 +308,16 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    PARCEL_READ_WITH_STATUS(std::optional<std::vector<android::base::unique_fd>>, readUniqueFileDescriptorVector),
    PARCEL_READ_WITH_STATUS(std::optional<std::vector<android::base::unique_fd>>, readUniqueFileDescriptorVector),
    PARCEL_READ_WITH_STATUS(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";
        FUZZ_LOG() << "about to readBlob";
        ::android::Parcel::ReadableBlob blob;
        ::android::Parcel::ReadableBlob blob;
        status_t status = p.readBlob(len, &blob);
        status_t status = p.readBlob(len, &blob);
        FUZZ_LOG() << "readBlob status: " << status;
        FUZZ_LOG() << "readBlob status: " << status;
    },
    },
    [] (const android::Parcel& p, uint8_t options) {
    [] (const ::android::Parcel& p, FuzzedDataProvider& provider) {
        FUZZ_LOG() << "about to readObject";
        FUZZ_LOG() << "about to readObject";
        bool nullMetaData = options & 0x1;
        bool nullMetaData = provider.ConsumeBool();
        const void* obj = static_cast<const void*>(p.readObject(nullMetaData));
        const void* obj = static_cast<const void*>(p.readObject(nullMetaData));
        FUZZ_LOG() << "readObject: " << obj;
        FUZZ_LOG() << "readObject: " << obj;
    },
    },
@@ -319,20 +325,19 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    PARCEL_READ_NO_STATUS(size_t, getOpenAshmemSize),
    PARCEL_READ_NO_STATUS(size_t, getOpenAshmemSize),


    // additional parcelable objects defined in libbinder
    // 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::os::ParcelableHolder;
        using ::android::Parcelable;
        using ::android::Parcelable;
        FUZZ_LOG() << "about to read ParcelableHolder using readParcelable with status";
        FUZZ_LOG() << "about to read ParcelableHolder using readParcelable with status";
        Parcelable::Stability stability = Parcelable::Stability::STABILITY_LOCAL;
        Parcelable::Stability stability = provider.ConsumeBool()
        if ( (data & 1) == 1 ) {
            ? Parcelable::Stability::STABILITY_LOCAL
            stability = Parcelable::Stability::STABILITY_VINTF;
            : Parcelable::Stability::STABILITY_VINTF;
        }
        ParcelableHolder t = ParcelableHolder(stability);
        ParcelableHolder t = ParcelableHolder(stability);
        status_t status = p.readParcelable(&t);
        status_t status = p.readParcelable(&t);
        FUZZ_LOG() << "ParcelableHolder status: " << status;
        FUZZ_LOG() << "ParcelableHolder status: " << status;
    },
    },
    PARCEL_READ_WITH_STATUS(android::os::PersistableBundle, readParcelable),
    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";
        FUZZ_LOG() << "about to call hasFileDescriptorsInRange() with status";
        size_t offset = p.readUint32();
        size_t offset = p.readUint32();
        size_t length = p.readUint32();
        size_t length = p.readUint32();
@@ -340,7 +345,7 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
        status_t status = p.hasFileDescriptorsInRange(offset, length, &result);
        status_t status = p.hasFileDescriptorsInRange(offset, length, &result);
        FUZZ_LOG() << " status: " << status  << " result: " << 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";
        FUZZ_LOG() << "about to call compareDataInRange() with status";
        size_t thisOffset = p.readUint32();
        size_t thisOffset = p.readUint32();
        size_t otherOffset = p.readUint32();
        size_t otherOffset = p.readUint32();
+14 −9
Original line number Original line Diff line number Diff line
@@ -70,7 +70,7 @@ binder_status_t ISomeInterface::readFromParcel(const AParcel* parcel,
}
}


#define PARCEL_READ(T, FUN)                                              \
#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"; \
        FUZZ_LOG() << "about to read " #T " using " #FUN " with status"; \
        T t{};                                                           \
        T t{};                                                           \
        binder_status_t status = FUN(p.aParcel(), &t);                   \
        binder_status_t status = FUN(p.aParcel(), &t);                   \
@@ -80,32 +80,37 @@ binder_status_t ISomeInterface::readFromParcel(const AParcel* parcel,
// clang-format off
// clang-format off
std::vector<ParcelRead<NdkParcelAdapter>> BINDER_NDK_PARCEL_READ_FUNCTIONS{
std::vector<ParcelRead<NdkParcelAdapter>> BINDER_NDK_PARCEL_READ_FUNCTIONS{
        // methods from binder_parcel.h
        // 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;
            FUZZ_LOG() << "about to set data position to " << pos;
            binder_status_t status = AParcel_setDataPosition(p.aParcel(), pos);
            binder_status_t status = AParcel_setDataPosition(p.aParcel(), pos);
            FUZZ_LOG() << "set data position: " << status;
            FUZZ_LOG() << "set data position: " << status;
        },
        },
        [](const NdkParcelAdapter& p, uint8_t /*data*/) {
        [](const NdkParcelAdapter& p, FuzzedDataProvider& /*provider*/) {
            FUZZ_LOG() << "about to read status header";
            FUZZ_LOG() << "about to read status header";
            ndk::ScopedAStatus t;
            ndk::ScopedAStatus t;
            binder_status_t status = AParcel_readStatusHeader(p.aParcel(), t.getR());
            binder_status_t status = AParcel_readStatusHeader(p.aParcel(), t.getR());
            FUZZ_LOG() << "read status header: " << status;
            FUZZ_LOG() << "read status header: " << status;
        },
        },
        [](const NdkParcelAdapter& p, uint8_t /*data*/) {
        [](const NdkParcelAdapter& p, FuzzedDataProvider& /*provider*/) {
            FUZZ_LOG() << "about to getDataSize the parcel";
            FUZZ_LOG() << "about to getDataSize the parcel";
            AParcel_getDataSize(p.aParcel());
            AParcel_getDataSize(p.aParcel());
            FUZZ_LOG() << "getDataSize done";
            FUZZ_LOG() << "getDataSize done";
        },
        },
        [](const NdkParcelAdapter& p, uint8_t data) {
        [](const NdkParcelAdapter& p, FuzzedDataProvider& provider) {
            FUZZ_LOG() << "about to read a ParcelableHolder";
            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);
            binder_status_t status = AParcel_readParcelable(p.aParcel(), &ph);
            FUZZ_LOG() << "read the ParcelableHolder: " << status;
            FUZZ_LOG() << "read the ParcelableHolder: " << status;
        },
        },
        [](const NdkParcelAdapter& p, uint8_t data) {
        [](const NdkParcelAdapter& p, FuzzedDataProvider& provider) {
            FUZZ_LOG() << "about to appendFrom";
            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();
            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);
            AParcel_delete(parcel);
            FUZZ_LOG() << "appendFrom: " << status;
            FUZZ_LOG() << "appendFrom: " << status;
        },
        },
+32 −25
Original line number Original line Diff line number Diff line
@@ -36,14 +36,14 @@ std::ostream& operator<<(std::ostream& os, const ::android::sp<::android::hardwa
    PARCEL_READ_NO_STATUS(T, FUN), PARCEL_READ_WITH_STATUS(T, FUN)
    PARCEL_READ_NO_STATUS(T, FUN), PARCEL_READ_WITH_STATUS(T, FUN)


#define PARCEL_READ_NO_STATUS(T, FUN)                                            \
#define PARCEL_READ_NO_STATUS(T, FUN)                                            \
    [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {\
    [](const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) { \
        FUZZ_LOG() << "about to read " #T " using " #FUN " with no status";      \
        FUZZ_LOG() << "about to read " #T " using " #FUN " with no status";      \
        T t = p.FUN();                                                           \
        T t = p.FUN();                                                           \
        FUZZ_LOG() << #T " value: " << t;                                        \
        FUZZ_LOG() << #T " value: " << t;                                        \
    }
    }


#define PARCEL_READ_WITH_STATUS(T, FUN)                                          \
#define PARCEL_READ_WITH_STATUS(T, FUN)                                          \
    [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {\
    [](const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) { \
        FUZZ_LOG() << "about to read " #T " using " #FUN " with status";         \
        FUZZ_LOG() << "about to read " #T " using " #FUN " with status";         \
        T t;                                                                     \
        T t;                                                                     \
        status_t status = p.FUN(&t);                                             \
        status_t status = p.FUN(&t);                                             \
@@ -56,27 +56,30 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
    PARCEL_READ_NO_STATUS(size_t, dataAvail),
    PARCEL_READ_NO_STATUS(size_t, dataAvail),
    PARCEL_READ_NO_STATUS(size_t, dataPosition),
    PARCEL_READ_NO_STATUS(size_t, dataPosition),
    PARCEL_READ_NO_STATUS(size_t, dataCapacity),
    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;
        FUZZ_LOG() << "about to setDataPosition: " << pos;
        p.setDataPosition(pos);
        p.setDataPosition(pos);
        FUZZ_LOG() << "setDataPosition done";
        FUZZ_LOG() << "setDataPosition done";
    },
    },
    [] (const ::android::hardware::Parcel& p, uint8_t length) {
    [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
        FUZZ_LOG() << "about to enforceInterface";
        FUZZ_LOG() << "about to enforceInterface";
        std::string interfaceName(length, 'a');
        bool okay = p.enforceInterface(provider.ConsumeRandomLengthString().c_str());
        bool okay = p.enforceInterface(interfaceName.c_str());
        FUZZ_LOG() << "enforceInterface status: " << okay;
        FUZZ_LOG() << "enforceInterface status: " << okay;
    },
    },
    PARCEL_READ_NO_STATUS(size_t, objectsCount),
    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";
        FUZZ_LOG() << "about to read";
        std::vector<uint8_t> data (length);
        std::vector<uint8_t> data (length);
        status_t status = p.read(data.data(), length);
        status_t status = p.read(data.data(), length);
        FUZZ_LOG() << "read status: " << status << " data: " << HexString(data.data(), data.size());
        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";
        FUZZ_LOG() << "about to read";
        std::vector<uint8_t> data (length);
        const void* inplace = p.readInplace(length);
        const void* inplace = p.readInplace(length);
        FUZZ_LOG() << "read status: " << (inplace ? HexString(inplace, length) : "null");
        FUZZ_LOG() << "read status: " << (inplace ? HexString(inplace, length) : "null");
    },
    },
@@ -91,14 +94,14 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
    PARCEL_READ_OPT_STATUS(float, readFloat),
    PARCEL_READ_OPT_STATUS(float, readFloat),
    PARCEL_READ_OPT_STATUS(double, readDouble),
    PARCEL_READ_OPT_STATUS(double, readDouble),
    PARCEL_READ_OPT_STATUS(bool, readBool),
    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";
        FUZZ_LOG() << "about to readCString";
        const char* str = p.readCString();
        const char* str = p.readCString();
        FUZZ_LOG() << "readCString " << (str ? str : "<null>");
        FUZZ_LOG() << "readCString " << (str ? str : "<null>");
    },
    },
    PARCEL_READ_OPT_STATUS(::android::String16, readString16),
    PARCEL_READ_OPT_STATUS(::android::String16, readString16),
    PARCEL_READ_WITH_STATUS(std::unique_ptr<::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";
        FUZZ_LOG() << "about to readString16Inplace";
        size_t outSize = 0;
        size_t outSize = 0;
        const char16_t* str = p.readString16Inplace(&outSize);
        const char16_t* str = p.readString16Inplace(&outSize);
@@ -106,7 +109,8 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
    },
    },
    PARCEL_READ_OPT_STATUS(::android::sp<::android::hardware::IBinder>, readStrongBinder),
    PARCEL_READ_OPT_STATUS(::android::sp<::android::hardware::IBinder>, readStrongBinder),
    PARCEL_READ_WITH_STATUS(::android::sp<::android::hardware::IBinder>, readNullableStrongBinder),
    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";
        FUZZ_LOG() << "about to readBuffer";
        size_t handle = 0;
        size_t handle = 0;
        const void* data = nullptr;
        const void* data = nullptr;
@@ -116,7 +120,8 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
        // should be null since we don't create any IPC objects
        // should be null since we don't create any IPC objects
        CHECK(data == nullptr) << data;
        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";
        FUZZ_LOG() << "about to readNullableBuffer";
        size_t handle = 0;
        size_t handle = 0;
        const void* data = nullptr;
        const void* data = nullptr;
@@ -126,7 +131,8 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
        // should be null since we don't create any IPC objects
        // should be null since we don't create any IPC objects
        CHECK(data == nullptr) << data;
        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";
        FUZZ_LOG() << "about to readEmbeddedBuffer";
        size_t handle = 0;
        size_t handle = 0;
        size_t parent_buffer_handle = 0;
        size_t parent_buffer_handle = 0;
@@ -138,7 +144,8 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
        // should be null since we don't create any IPC objects
        // should be null since we don't create any IPC objects
        CHECK(data == nullptr) << data;
        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";
        FUZZ_LOG() << "about to readNullableEmbeddedBuffer";
        size_t handle = 0;
        size_t handle = 0;
        size_t parent_buffer_handle = 0;
        size_t parent_buffer_handle = 0;
@@ -150,7 +157,7 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
        // should be null since we don't create any IPC objects
        // should be null since we don't create any IPC objects
        CHECK(data == nullptr) << data;
        CHECK(data == nullptr) << data;
    },
    },
    [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
    [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) {
        FUZZ_LOG() << "about to readNativeHandleNoDup";
        FUZZ_LOG() << "about to readNativeHandleNoDup";
        const native_handle_t* handle = nullptr;
        const native_handle_t* handle = nullptr;
        status_t status = p.readNativeHandleNoDup(&handle);
        status_t status = p.readNativeHandleNoDup(&handle);
+6 −11
Original line number Original line Diff line number Diff line
@@ -83,19 +83,14 @@ void doReadFuzz(const char* backend, const std::vector<ParcelRead<P>>& reads,
    FUZZ_LOG() << "input: " << HexString(p.data(), p.dataSize());
    FUZZ_LOG() << "input: " << HexString(p.data(), p.dataSize());
    FUZZ_LOG() << "instructions: " << HexString(instructions.data(), instructions.size());
    FUZZ_LOG() << "instructions: " << HexString(instructions.data(), instructions.size());


    for (size_t i = 0; i + 1 < instructions.size(); i += 2) {
    FuzzedDataProvider instructionsProvider(instructions.data(), instructions.size());
        uint8_t a = instructions[i];
    while (instructionsProvider.remaining_bytes() > 0) {
        uint8_t readIdx = a % reads.size();
        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
        reads[idx](p, instructionsProvider);
                   << " 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);
    }
    }
}
}


+5 −1
Original line number Original line Diff line number Diff line
@@ -15,5 +15,9 @@
 */
 */
#pragma once
#pragma once


#include <fuzzer/FuzzedDataProvider.h>

#include <functional>

template <typename P>
template <typename P>
using ParcelRead = std::function<void(const P& p, uint8_t data)>;
using ParcelRead = std::function<void(const P& p, FuzzedDataProvider& provider)>;