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

Commit 74890c7b authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "binder_parcel_fuzzer: instrs w/ FuzzedDataProvider" am: a4b581ad

parents 295eed4f a4b581ad
Loading
Loading
Loading
Loading
+39 −34
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ struct BigStruct {
};

#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"; \
        T t{};                                                           \
        status_t status = p.FUN(&t);                                     \
@@ -82,7 +82,7 @@ struct BigStruct {
    }

#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"; \
        T t = p.FUN();                                                      \
        (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, 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 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    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 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    },
    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 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    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 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    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 @@ 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),
#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 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    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 @@ 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::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 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    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 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
        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();
+14 −9
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ binder_status_t ISomeInterface::readFromParcel(const AParcel* parcel,
}

#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 @@ binder_status_t ISomeInterface::readFromParcel(const AParcel* parcel,
// 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;
        },
+32 −25
Original line number 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)

#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";      \
        T t = p.FUN();                                                           \
        FUZZ_LOG() << #T " value: " << t;                                        \
    }

#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";         \
        T 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, 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 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
    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 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
    },
    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 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
        // 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 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
        // 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 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
        // 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 @@ std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTI
        // 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);
+6 −11
Original line number 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() << "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);
    }
}

+5 −1
Original line number Diff line number Diff line
@@ -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)>;