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

Commit 1fe2ef49 authored by Steven Moreland's avatar Steven Moreland Committed by Automerger Merge Worker
Browse files

Merge "fuzzer driver: more fd types" am: 97fc2289 am: 202d7a19

parents b4136b24 202d7a19
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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
+4 −1
Original line number Diff line number Diff line
@@ -33,10 +33,13 @@ struct RandomParcelOptions {
/**
 * 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
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ 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()), options);
        fillRandomParcel(&data, FuzzedDataProvider(subData.data(), subData.size()), &options);

        Parcel reply;
        (void)target->transact(code, data, &reply, flags);
+19 −7
Original line number Diff line number Diff line
@@ -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 @@ void doTransactFuzz(const char* backend, const sp<B>& binder, FuzzedDataProvider

    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 @@ void doReadFuzz(const char* backend, const std::vector<ParcelRead<P>>& reads,
    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 @@ void doAppendFuzz(const char* backend, FuzzedDataProvider&& provider) {
    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;
+37 −6
Original line number Diff line number Diff line
@@ -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
Loading