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

Commit 22acd027 authored by Steven Moreland's avatar Steven Moreland
Browse files

libbinder_random_parcel: splitout random binder

In preparation for more complicated random binders. Random
binders here are now symmetrical wrt FD logic.

This slightly changes the probabilities different kinds of
binders will used from random inputs, but it's not expected
to change coverage for arbitrary fuzzers.

Bug: 241923341
Test: binder_parcel_fuzzer
Change-Id: I9c3728cd2cde9a8abc62efecf1f567f366a38514
parent 08182687
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ cc_library_static {
        },
    },
    srcs: [
        "random_binder.cpp",
        "random_fd.cpp",
        "random_parcel.cpp",
        "libbinder_driver.cpp",
+29 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <binder/IBinder.h>
#include <fuzzer/FuzzedDataProvider.h>

namespace android {

// Get a random binder object for use in fuzzing.
//
// may return multiple FDs (e.g. pipe), but will always return at least one
sp<IBinder> getRandomBinder(FuzzedDataProvider* provider);

} // namespace android
+52 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <fuzzbinder/random_binder.h>

#include <binder/IInterface.h>
#include <binder/IServiceManager.h>

namespace android {

class NamedBinder : public BBinder {
public:
    NamedBinder(const String16& descriptor) : mDescriptor(descriptor) {}
    const String16& getInterfaceDescriptor() const override { return mDescriptor; }

private:
    String16 mDescriptor;
};

sp<IBinder> getRandomBinder(FuzzedDataProvider* provider) {
    auto makeFunc = provider->PickValueInArray<const std::function<sp<IBinder>()>>({
            [&]() {
                // descriptor is the length of a class name, e.g.
                // "some.package.Foo"
                std::string str = provider->ConsumeRandomLengthString(100 /*max length*/);
                return new NamedBinder(String16(str.c_str()));
            },
            []() {
                // this is the easiest remote binder to get ahold of, and it
                // should be able to handle anything thrown at it, and
                // essentially every process can talk to it, so it's a good
                // candidate for checking usage of an actual BpBinder
                return IInterface::asBinder(defaultServiceManager());
            },
            [&]() -> sp<IBinder> { return nullptr; },
    });
    return makeFunc();
}

} // namespace android
+11 −36
Original line number Diff line number Diff line
@@ -17,23 +17,14 @@
#include <fuzzbinder/random_parcel.h>

#include <android-base/logging.h>
#include <binder/IServiceManager.h>
#include <binder/RpcSession.h>
#include <binder/RpcTransportRaw.h>
#include <fuzzbinder/random_binder.h>
#include <fuzzbinder/random_fd.h>
#include <utils/String16.h>

namespace android {

class NamedBinder : public BBinder {
public:
    NamedBinder(const String16& descriptor) : mDescriptor(descriptor) {}
    const String16& getInterfaceDescriptor() const override { return mDescriptor; }

private:
    String16 mDescriptor;
};

static void fillRandomParcelData(Parcel* p, FuzzedDataProvider&& provider) {
    std::vector<uint8_t> data = provider.ConsumeBytes<uint8_t>(provider.remaining_bytes());
    CHECK(OK == p->write(data.data(), data.size()));
@@ -89,32 +80,16 @@ void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider, RandomParcelOpti
                },
                // write binder
                [&]() {
                    auto makeFunc = provider.PickValueInArray<const std::function<sp<IBinder>()>>({
                            [&]() {
                                // descriptor is the length of a class name, e.g.
                                // "some.package.Foo"
                                std::string str =
                                        provider.ConsumeRandomLengthString(100 /*max length*/);
                                return new NamedBinder(String16(str.c_str()));
                            },
                            []() {
                                // this is the easiest remote binder to get ahold of, and it
                                // should be able to handle anything thrown at it, and
                                // essentially every process can talk to it, so it's a good
                                // candidate for checking usage of an actual BpBinder
                                return IInterface::asBinder(defaultServiceManager());
                            },
                            [&]() -> sp<IBinder> {
                    sp<IBinder> binder;
                    if (options->extraBinders.size() > 0 && provider.ConsumeBool()) {
                                    return options->extraBinders.at(
                                            provider.ConsumeIntegralInRange<
                                                    size_t>(0, options->extraBinders.size() - 1));
                        binder = options->extraBinders.at(
                                provider.ConsumeIntegralInRange<size_t>(0,
                                                                        options->extraBinders
                                                                                        .size() -
                                                                                1));
                    } else {
                                    return nullptr;
                        binder = getRandomBinder(&provider);
                    }
                            },
                    });
                    sp<IBinder> binder = makeFunc();
                    CHECK(OK == p->writeStrongBinder(binder));
                },
        });