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

Commit f61c0471 authored by Harry Cutts's avatar Harry Cutts
Browse files

inputflinger fuzzers: Remove FuzzContainer

As discussed on the touchpad fuzzer CL [0], FuzzContainer was hiding
quite a bit of internal state and making fuzzers harder to understand.
Its constructor appeared to be deduplicating code, but looking more
closely, it wasn't really helping that much, especially for the most
common cases. Replace it with a few static methods, making it clearer
how state is being changed in the fuzzers.

[0] Change ID Ic22ac0f29d433fdf3c17331df620a39937ebd7eb

Bug: 245989146
Test: build and briefly run all modified fuzzers
      $ SANITIZE_TARGET=hwaddress make ${FUZZER_NAME}
      $ cd $ANDROID_PRODUCT_OUT
      $ adb root
      $ adb sync data
      $ adb shell /data/fuzz/$(get_build_var TARGET_ARCH)/${FUZZER_NAME}/${FUZZER_NAME}

Change-Id: I6e28b1f5ec62dc2d084173c1eb461c4bb699678b
parent 2455b77d
Loading
Loading
Loading
Loading
+19 −10
Original line number Diff line number Diff line
@@ -15,22 +15,22 @@
 */

#include <CursorInputMapper.h>
#include <FuzzContainer.h>
#include <InputDevice.h>
#include <InputReaderBase.h>
#include <MapperHelpers.h>

namespace android {

static void addProperty(FuzzContainer& fuzzer, std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp) {
static void addProperty(FuzzEventHub& eventHub, std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp) {
    // Pick a random property to set for the mapper to have set.
    fdp->PickValueInArray<std::function<void()>>(
            {[&]() -> void { fuzzer.addProperty("cursor.mode", "pointer"); },
             [&]() -> void { fuzzer.addProperty("cursor.mode", "navigation"); },
            {[&]() -> void { eventHub.addProperty("cursor.mode", "pointer"); },
             [&]() -> void { eventHub.addProperty("cursor.mode", "navigation"); },
             [&]() -> void {
                 fuzzer.addProperty("cursor.mode", fdp->ConsumeRandomLengthString(100).data());
                 eventHub.addProperty("cursor.mode", fdp->ConsumeRandomLengthString(100).data());
             },
             [&]() -> void {
                 fuzzer.addProperty("cursor.orientationAware",
                 eventHub.addProperty("cursor.orientationAware",
                                      fdp->ConsumeRandomLengthString(100).data());
             }})();
}
@@ -38,15 +38,24 @@ static void addProperty(FuzzContainer& fuzzer, std::shared_ptr<ThreadSafeFuzzedD
extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
    std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp =
            std::make_shared<ThreadSafeFuzzedDataProvider>(data, size);
    FuzzContainer fuzzer(fdp);

    // Create mocked objects to support the fuzzed input mapper.
    std::shared_ptr<FuzzEventHub> eventHub = std::make_shared<FuzzEventHub>(fdp);
    FuzzInputReaderContext context(eventHub, fdp);
    InputDevice device = getFuzzedInputDevice(*fdp, &context);

    InputReaderConfiguration policyConfig;
    CursorInputMapper& mapper = fuzzer.getMapper<CursorInputMapper>(policyConfig);
    CursorInputMapper& mapper =
            getMapperForDevice<ThreadSafeFuzzedDataProvider, CursorInputMapper>(*fdp.get(), device,
                                                                                policyConfig);

    // Loop through mapper operations until randomness is exhausted.
    while (fdp->remaining_bytes() > 0) {
        fdp->PickValueInArray<std::function<void()>>({
                [&]() -> void { addProperty(fuzzer, fdp); },
                [&]() -> void {
                    addProperty(*eventHub.get(), fdp);
                    configureAndResetDevice(*fdp, device);
                },
                [&]() -> void {
                    std::string dump;
                    mapper.dump(dump);
+0 −86
Original line number Diff line number Diff line
/*
 * Copyright 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 <InputDevice.h>
#include <InputMapper.h>
#include <InputReader.h>
#include <MapperHelpers.h>

namespace android {

class FuzzContainer {
    std::shared_ptr<FuzzEventHub> mFuzzEventHub;
    FuzzInputListener mFuzzListener;
    std::unique_ptr<FuzzInputReaderContext> mFuzzContext;
    std::unique_ptr<InputDevice> mFuzzDevice;
    std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp;

public:
    FuzzContainer(std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp) : mFdp(fdp) {
        // Setup parameters.
        std::string deviceName = mFdp->ConsumeRandomLengthString(16);
        std::string deviceLocation = mFdp->ConsumeRandomLengthString(12);
        int32_t deviceID = mFdp->ConsumeIntegralInRange<int32_t>(0, 5);
        int32_t deviceGeneration = mFdp->ConsumeIntegralInRange<int32_t>(/*from=*/0, /*to=*/5);

        // Create mocked objects.
        mFuzzEventHub = std::make_shared<FuzzEventHub>(mFdp);
        sp<FuzzInputReaderPolicy> policy = sp<FuzzInputReaderPolicy>::make(mFdp);
        mFuzzContext = std::make_unique<FuzzInputReaderContext>(mFuzzEventHub, policy,
                                                                mFuzzListener, mFdp);

        InputDeviceIdentifier identifier;
        identifier.name = deviceName;
        identifier.location = deviceLocation;
        mFuzzDevice = std::make_unique<InputDevice>(mFuzzContext.get(), deviceID, deviceGeneration,
                                                    identifier);
    }

    ~FuzzContainer() {}

    void configureDevice() {
        nsecs_t arbitraryTime = mFdp->ConsumeIntegral<nsecs_t>();
        std::list<NotifyArgs> out;
        out += mFuzzDevice->configure(arbitraryTime, /*readerConfig=*/{}, /*changes=*/{});
        out += mFuzzDevice->reset(arbitraryTime);
        for (const NotifyArgs& args : out) {
            mFuzzListener.notify(args);
        }
    }

    void addProperty(std::string key, std::string value) {
        mFuzzEventHub->addProperty(key, value);
        configureDevice();
    }

    void setAbsoluteAxisInfo(int axis, const RawAbsoluteAxisInfo& axisInfo) {
        mFuzzEventHub->setAbsoluteAxisInfo(mFuzzDevice->getId(), axis, axisInfo);
    }

    template <class T, typename... Args>
    T& getMapper(Args... args) {
        int32_t eventhubId = mFdp->ConsumeIntegral<int32_t>();
        // ensure a device entry exists for this eventHubId
        mFuzzDevice->addEmptyEventHubDevice(eventhubId);
        configureDevice();

        return mFuzzDevice->template constructAndAddMapper<T>(eventhubId, args...);
    }
};

} // namespace android
+20 −15
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

#include <FuzzContainer.h>
#include <InputDevice.h>
#include <InputReaderBase.h>
#include <KeyboardInputMapper.h>
#include <MapperHelpers.h>
@@ -23,20 +23,20 @@ namespace android {

const int32_t kMaxKeycodes = 100;

static void addProperty(FuzzContainer& fuzzer, std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp) {
static void addProperty(FuzzEventHub& eventHub, std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp) {
    // Pick a random property to set for the mapper to have set.
    fdp->PickValueInArray<std::function<void()>>(
            {[&]() -> void { fuzzer.addProperty("keyboard.orientationAware", "1"); },
            {[&]() -> void { eventHub.addProperty("keyboard.orientationAware", "1"); },
             [&]() -> void {
                 fuzzer.addProperty("keyboard.orientationAware",
                 eventHub.addProperty("keyboard.orientationAware",
                                      fdp->ConsumeRandomLengthString(100).data());
             },
             [&]() -> void {
                 fuzzer.addProperty("keyboard.doNotWakeByDefault",
                 eventHub.addProperty("keyboard.doNotWakeByDefault",
                                      fdp->ConsumeRandomLengthString(100).data());
             },
             [&]() -> void {
                 fuzzer.addProperty("keyboard.handlesKeyRepeat",
                 eventHub.addProperty("keyboard.handlesKeyRepeat",
                                      fdp->ConsumeRandomLengthString(100).data());
             }})();
}
@@ -44,17 +44,22 @@ static void addProperty(FuzzContainer& fuzzer, std::shared_ptr<ThreadSafeFuzzedD
extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
    std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp =
            std::make_shared<ThreadSafeFuzzedDataProvider>(data, size);
    FuzzContainer fuzzer(fdp);

    KeyboardInputMapper& mapper =
            fuzzer.getMapper<KeyboardInputMapper>(InputReaderConfiguration{},
                                                  fdp->ConsumeIntegral<uint32_t>(),
                                                  fdp->ConsumeIntegral<int32_t>());
    // Create mocked objects to support the fuzzed input mapper.
    std::shared_ptr<FuzzEventHub> eventHub = std::make_shared<FuzzEventHub>(fdp);
    FuzzInputReaderContext context(eventHub, fdp);
    InputDevice device = getFuzzedInputDevice(*fdp, &context);

    KeyboardInputMapper& mapper = getMapperForDevice<
            ThreadSafeFuzzedDataProvider,
            KeyboardInputMapper>(*fdp.get(), device, InputReaderConfiguration{},
                                 /*source=*/fdp->ConsumeIntegral<uint32_t>(),
                                 /*keyboardType=*/fdp->ConsumeIntegral<int32_t>());

    // Loop through mapper operations until randomness is exhausted.
    while (fdp->remaining_bytes() > 0) {
        fdp->PickValueInArray<std::function<void()>>({
                [&]() -> void { addProperty(fuzzer, fdp); },
                [&]() -> void { addProperty(*eventHub.get(), fdp); },
                [&]() -> void {
                    std::string dump;
                    mapper.dump(dump);
+31 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#pragma once

#include <map>
#include <memory>

#include <EventHub.h>
#include <InputDevice.h>
@@ -328,10 +329,8 @@ class FuzzInputReaderContext : public InputReaderContext {

public:
    FuzzInputReaderContext(std::shared_ptr<EventHubInterface> eventHub,
                           const sp<InputReaderPolicyInterface>& policy,
                           InputListenerInterface& listener,
                           std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp)
          : mEventHub(eventHub), mPolicy(policy), mFdp(mFdp) {}
                           std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp)
          : mEventHub(eventHub), mPolicy(sp<FuzzInputReaderPolicy>::make(fdp)), mFdp(fdp) {}
    ~FuzzInputReaderContext() {}
    void updateGlobalMetaState() override {}
    int32_t getGlobalMetaState() { return mFdp->ConsumeIntegral<int32_t>(); }
@@ -358,4 +357,32 @@ public:
    void notifyStylusGestureStarted(int32_t, nsecs_t) {}
};

template <class Fdp>
InputDevice getFuzzedInputDevice(Fdp& fdp, FuzzInputReaderContext* context) {
    InputDeviceIdentifier identifier;
    identifier.name = fdp.ConsumeRandomLengthString(16);
    identifier.location = fdp.ConsumeRandomLengthString(12);
    int32_t deviceID = fdp.ConsumeIntegralInRange(0, 5);
    int32_t deviceGeneration = fdp.ConsumeIntegralInRange(0, 5);
    return InputDevice(context, deviceID, deviceGeneration, identifier);
}

template <class Fdp>
void configureAndResetDevice(Fdp& fdp, InputDevice& device) {
    nsecs_t arbitraryTime = fdp.template ConsumeIntegral<nsecs_t>();
    std::list<NotifyArgs> out;
    out += device.configure(arbitraryTime, /*readerConfig=*/{}, /*changes=*/{});
    out += device.reset(arbitraryTime);
}

template <class Fdp, class T, typename... Args>
T& getMapperForDevice(Fdp& fdp, InputDevice& device, Args... args) {
    int32_t eventhubId = fdp.template ConsumeIntegral<int32_t>();
    // ensure a device entry exists for this eventHubId
    device.addEmptyEventHubDevice(eventhubId);
    configureAndResetDevice(fdp, device);

    return device.template constructAndAddMapper<T>(eventhubId, args...);
}

} // namespace android
+29 −19
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

#include <FuzzContainer.h>
#include <InputDevice.h>
#include <InputReaderBase.h>
#include <MapperHelpers.h>
#include <MultiTouchInputMapper.h>
@@ -23,37 +23,37 @@ namespace android {

const int32_t kMaxKeycodes = 100;

static void addProperty(FuzzContainer& fuzzer, std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp) {
static void addProperty(FuzzEventHub& eventHub, std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp) {
    // Pick a random property to set for the mapper to have set.
    fdp->PickValueInArray<std::function<void()>>(
            {[&]() -> void { fuzzer.addProperty("touch.deviceType", "touchScreen"); },
            {[&]() -> void { eventHub.addProperty("touch.deviceType", "touchScreen"); },
             [&]() -> void {
                 fuzzer.addProperty("touch.deviceType", fdp->ConsumeRandomLengthString(8).data());
                 eventHub.addProperty("touch.deviceType", fdp->ConsumeRandomLengthString(8).data());
             },
             [&]() -> void {
                 fuzzer.addProperty("touch.size.scale", fdp->ConsumeRandomLengthString(8).data());
                 eventHub.addProperty("touch.size.scale", fdp->ConsumeRandomLengthString(8).data());
             },
             [&]() -> void {
                 fuzzer.addProperty("touch.size.bias", fdp->ConsumeRandomLengthString(8).data());
                 eventHub.addProperty("touch.size.bias", fdp->ConsumeRandomLengthString(8).data());
             },
             [&]() -> void {
                 fuzzer.addProperty("touch.size.isSummed",
                 eventHub.addProperty("touch.size.isSummed",
                                      fdp->ConsumeRandomLengthString(8).data());
             },
             [&]() -> void {
                 fuzzer.addProperty("touch.size.calibration",
                 eventHub.addProperty("touch.size.calibration",
                                      fdp->ConsumeRandomLengthString(8).data());
             },
             [&]() -> void {
                 fuzzer.addProperty("touch.pressure.scale",
                 eventHub.addProperty("touch.pressure.scale",
                                      fdp->ConsumeRandomLengthString(8).data());
             },
             [&]() -> void {
                 fuzzer.addProperty("touch.size.calibration",
                 eventHub.addProperty("touch.size.calibration",
                                      fdp->ConsumeBool() ? "diameter" : "area");
             },
             [&]() -> void {
                 fuzzer.addProperty("touch.pressure.calibration",
                 eventHub.addProperty("touch.pressure.calibration",
                                      fdp->ConsumeRandomLengthString(8).data());
             }})();
}
@@ -61,15 +61,25 @@ static void addProperty(FuzzContainer& fuzzer, std::shared_ptr<ThreadSafeFuzzedD
extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
    std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp =
            std::make_shared<ThreadSafeFuzzedDataProvider>(data, size);
    FuzzContainer fuzzer(fdp);

    // Create mocked objects to support the fuzzed input mapper.
    std::shared_ptr<FuzzEventHub> eventHub = std::make_shared<FuzzEventHub>(fdp);
    FuzzInputReaderContext context(eventHub, fdp);
    InputDevice device = getFuzzedInputDevice(*fdp, &context);

    InputReaderConfiguration policyConfig;
    MultiTouchInputMapper& mapper = fuzzer.getMapper<MultiTouchInputMapper>(policyConfig);
    MultiTouchInputMapper& mapper =
            getMapperForDevice<ThreadSafeFuzzedDataProvider, MultiTouchInputMapper>(*fdp.get(),
                                                                                    device,
                                                                                    policyConfig);

    // Loop through mapper operations until randomness is exhausted.
    while (fdp->remaining_bytes() > 0) {
        fdp->PickValueInArray<std::function<void()>>({
                [&]() -> void { addProperty(fuzzer, fdp); },
                [&]() -> void {
                    addProperty(*eventHub.get(), fdp);
                    configureAndResetDevice(*fdp, device);
                },
                [&]() -> void {
                    std::string dump;
                    mapper.dump(dump);
Loading