DO NOT MERGE Add initial batch of inputFlinger fuzzers
This batch of fuzzers is focused on the input Mappers. These fuzzers are
not host_supported, and must be run on-device. Followup CLs containing
additional inputflinger fuzzers will rely on the FuzzContainer.h and
MapperHelpers.h header files.
Fuzzers included:
- CursorInputFuzzer
- KeyboardInputFuzzer
- MultiTouchInputFuzzer
- SwitchInputFuzzer
Test: Tested on a pixel 3a with HWASAN. Accurate % coverage information is
not available due to the large number of shared libraries included
in runs built with hwasan interfering with PC Count information
(increasing the total PC count to ~682,000).
Signed-off-by: Michael Ensing <michael.ensing@leviathansecurity.com>
Change-Id: Id39205c691f54c516f8a452293cb098382019335
diff --git a/services/inputflinger/tests/fuzzers/Android.bp b/services/inputflinger/tests/fuzzers/Android.bp
new file mode 100644
index 0000000..830925a
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/Android.bp
@@ -0,0 +1,82 @@
+//
+// Copyright (C) 2020 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.
+//
+
+cc_defaults {
+ name: "inputflinger_fuzz_defaults",
+ defaults: [
+ "inputflinger_defaults",
+ ],
+ include_dirs: [
+ "frameworks/native/services/inputflinger",
+ ],
+ shared_libs: [
+ "android.hardware.input.classifier@1.0",
+ "libbase",
+ "libbinder",
+ "libcutils",
+ "liblog",
+ "libutils",
+ "libui",
+ "libinput",
+ "libinputflinger",
+ "libinputreader",
+ "libinputflinger_base",
+ "libstatslog",
+ ],
+ header_libs: [
+ "libinputreader_headers",
+ ],
+}
+
+cc_fuzz {
+ name: "inputflinger_cursor_input_fuzzer",
+ defaults: [
+ "inputflinger_fuzz_defaults",
+ ],
+ srcs: [
+ "CursorInputFuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "inputflinger_keyboard_input_fuzzer",
+ defaults: [
+ "inputflinger_fuzz_defaults",
+ ],
+ srcs: [
+ "KeyboardInputFuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "inputflinger_multitouch_input_fuzzer",
+ defaults: [
+ "inputflinger_fuzz_defaults",
+ ],
+ srcs: [
+ "MultiTouchInputFuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "inputflinger_switch_input_fuzzer",
+ defaults: [
+ "inputflinger_fuzz_defaults",
+ ],
+ srcs: [
+ "SwitchInputFuzzer.cpp",
+ ],
+}
diff --git a/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
new file mode 100644
index 0000000..8aa7434
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2020 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 <CursorInputMapper.h>
+#include <FuzzContainer.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+void addProperty(FuzzContainer& fuzzer, std::shared_ptr<FuzzedDataProvider> fdp) {
+ // Pick a random property to set for the mapper to have set.
+ fdp->PickValueInArray<std::function<void()>>(
+ {[&]() -> void { fuzzer.addProperty(String8("cursor.mode"), String8("pointer")); },
+ [&]() -> void { fuzzer.addProperty(String8("cursor.mode"), String8("navigation")); },
+ [&]() -> void {
+ fuzzer.addProperty(String8("cursor.mode"),
+ String8(fdp->ConsumeRandomLengthString(100).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("cursor.orientationAware"),
+ String8(fdp->ConsumeRandomLengthString(100).data()));
+ }})();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+ std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+ FuzzContainer fuzzer = FuzzContainer(fdp);
+
+ CursorInputMapper& mapper = fuzzer.getMapper<CursorInputMapper>();
+ auto policyConfig = fuzzer.getPolicyConfig();
+
+ // Loop through mapper operations until randomness is exhausted.
+ while (fdp->remaining_bytes() > 0) {
+ fdp->PickValueInArray<std::function<void()>>({
+ [&]() -> void { addProperty(fuzzer, fdp); },
+ [&]() -> void {
+ std::string dump;
+ mapper.dump(dump);
+ },
+ [&]() -> void { mapper.getSources(); },
+ [&]() -> void {
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ // Need to reconfigure with 0 or you risk a NPE.
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+ InputDeviceInfo info;
+ mapper.populateDeviceInfo(&info);
+ },
+ [&]() -> void {
+ // Need to reconfigure with 0 or you risk a NPE.
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+ RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ mapper.process(&rawEvent);
+ },
+ [&]() -> void { mapper.reset(fdp->ConsumeIntegral<nsecs_t>()); },
+ [&]() -> void {
+ mapper.getScanCodeState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ // Need to reconfigure with 0 or you risk a NPE.
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+ mapper.getAssociatedDisplayId();
+ },
+ })();
+ }
+
+ return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/FuzzContainer.h b/services/inputflinger/tests/fuzzers/FuzzContainer.h
new file mode 100644
index 0000000..84f0566
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/FuzzContainer.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020 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>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+class FuzzContainer {
+ int32_t meventID;
+ std::shared_ptr<FuzzEventHub> mFuzzEventHub;
+ sp<FuzzInputReaderPolicy> mFuzzPolicy;
+ sp<FuzzInputListener> mFuzzListener;
+ std::unique_ptr<FuzzInputReaderContext> mFuzzContext;
+ std::unique_ptr<InputDevice> mFuzzDevice;
+ InputReaderConfiguration mPolicyConfig;
+ std::shared_ptr<FuzzedDataProvider> fdp;
+
+public:
+ FuzzContainer(std::shared_ptr<FuzzedDataProvider> fdp) : fdp(fdp) {
+ // Setup parameters.
+ std::string deviceName = fdp->ConsumeRandomLengthString(16);
+ std::string deviceLocation = fdp->ConsumeRandomLengthString(12);
+ int32_t deviceID = fdp->ConsumeIntegralInRange<int32_t>(0, 5);
+ int32_t deviceGeneration = fdp->ConsumeIntegralInRange<int32_t>(0, 5);
+ meventID = fdp->ConsumeIntegral<int32_t>();
+
+ // Create mocked objects.
+ mFuzzEventHub = std::make_shared<FuzzEventHub>(fdp);
+ mFuzzPolicy = new FuzzInputReaderPolicy(fdp);
+ mFuzzListener = new FuzzInputListener();
+ mFuzzContext = std::make_unique<FuzzInputReaderContext>(mFuzzEventHub, mFuzzPolicy,
+ mFuzzListener, fdp);
+
+ InputDeviceIdentifier identifier;
+ identifier.name = deviceName;
+ identifier.location = deviceLocation;
+ mFuzzDevice = std::make_unique<InputDevice>(mFuzzContext.get(), deviceID, deviceGeneration,
+ identifier);
+ mFuzzPolicy->getReaderConfiguration(&mPolicyConfig);
+ }
+
+ ~FuzzContainer() {}
+
+ void configureDevice() {
+ nsecs_t arbitraryTime = fdp->ConsumeIntegral<nsecs_t>();
+ mFuzzDevice->configure(arbitraryTime, &mPolicyConfig, 0);
+ mFuzzDevice->reset(arbitraryTime);
+ }
+
+ void addProperty(const String8& key, const String8& value) {
+ mFuzzEventHub->addProperty(key, value);
+ configureDevice();
+ }
+
+ InputReaderConfiguration& getPolicyConfig() { return mPolicyConfig; }
+
+ template <class T, typename... Args>
+ T& getMapper(Args... args) {
+ T& mapper = mFuzzDevice->addMapper<T>(fdp->ConsumeIntegral<int32_t>(), args...);
+ configureDevice();
+ return mapper;
+ }
+};
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
new file mode 100644
index 0000000..854e2fd
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2020 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 <FuzzContainer.h>
+#include <KeyboardInputMapper.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+void addProperty(FuzzContainer& fuzzer, std::shared_ptr<FuzzedDataProvider> fdp) {
+ // Pick a random property to set for the mapper to have set.
+ fdp->PickValueInArray<std::function<void()>>(
+ {[&]() -> void {
+ fuzzer.addProperty(String8("keyboard.orientationAware"), String8("1"));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("keyboard.orientationAware"),
+ String8(fdp->ConsumeRandomLengthString(100).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("keyboard.doNotWakeByDefault"),
+ String8(fdp->ConsumeRandomLengthString(100).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("keyboard.handlesKeyRepeat"),
+ String8(fdp->ConsumeRandomLengthString(100).data()));
+ }})();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+ std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+ FuzzContainer fuzzer = FuzzContainer(fdp);
+
+ KeyboardInputMapper& mapper =
+ fuzzer.getMapper<KeyboardInputMapper>(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ auto policyConfig = fuzzer.getPolicyConfig();
+
+ // Loop through mapper operations until randomness is exhausted.
+ while (fdp->remaining_bytes() > 0) {
+ fdp->PickValueInArray<std::function<void()>>({
+ [&]() -> void { addProperty(fuzzer, fdp); },
+ [&]() -> void {
+ std::string dump;
+ mapper.dump(dump);
+ },
+ [&]() -> void {
+ InputDeviceInfo info;
+ mapper.populateDeviceInfo(&info);
+ },
+ [&]() -> void { mapper.getSources(); },
+ [&]() -> void {
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+ fdp->ConsumeIntegral<uint32_t>());
+ },
+ [&]() -> void { mapper.reset(fdp->ConsumeIntegral<nsecs_t>()); },
+ [&]() -> void {
+ RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ mapper.process(&rawEvent);
+ },
+ [&]() -> void {
+ mapper.getKeyCodeState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ mapper.getScanCodeState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ mapper.markSupportedKeyCodes(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<size_t>(), nullptr, nullptr);
+ },
+ [&]() -> void { mapper.getMetaState(); },
+ [&]() -> void { mapper.updateMetaState(fdp->ConsumeIntegral<int32_t>()); },
+ [&]() -> void { mapper.getAssociatedDisplayId(); },
+ })();
+ }
+
+ return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h
new file mode 100644
index 0000000..edfb68d
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2020 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 <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+class FuzzEventHub : public EventHubInterface {
+ InputDeviceIdentifier mIdentifier;
+ std::vector<TouchVideoFrame> mVideoFrames;
+ PropertyMap mFuzzConfig;
+ std::mutex mEventLock;
+ size_t mCount = 0;
+ RawEvent mBuf[256];
+ std::shared_ptr<FuzzedDataProvider> fdp;
+
+public:
+ FuzzEventHub(std::shared_ptr<FuzzedDataProvider> fdp) : fdp(fdp) {}
+ ~FuzzEventHub() {}
+ void addProperty(const String8& key, const String8 value) {
+ mFuzzConfig.addProperty(key, value);
+ }
+ void addEvents(std::shared_ptr<FuzzedDataProvider> fdp) {
+ std::lock_guard<std::mutex> guard(mEventLock);
+ mCount = fdp->ConsumeIntegralInRange<size_t>(0, 256);
+
+ for (size_t i = 0; i < mCount; i++)
+ mBuf[i] = {fdp->ConsumeIntegral<nsecs_t>(), fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ }
+ uint32_t getDeviceClasses(int32_t deviceId) const override {
+ return fdp->ConsumeIntegral<uint32_t>();
+ }
+ InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const override {
+ return mIdentifier;
+ }
+ int32_t getDeviceControllerNumber(int32_t deviceId) const override {
+ return fdp->ConsumeIntegral<int32_t>();
+ }
+ void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const override {
+ *outConfiguration = mFuzzConfig;
+ }
+ status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+ RawAbsoluteAxisInfo* outAxisInfo) const override {
+ return fdp->ConsumeIntegral<status_t>();
+ }
+ bool hasRelativeAxis(int32_t deviceId, int axis) const override { return fdp->ConsumeBool(); }
+ bool hasInputProperty(int32_t deviceId, int property) const override {
+ return fdp->ConsumeBool();
+ }
+ status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState,
+ int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const override {
+ return fdp->ConsumeIntegral<status_t>();
+ }
+ status_t mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const override {
+ return fdp->ConsumeIntegral<status_t>();
+ }
+ void setExcludedDevices(const std::vector<std::string>& devices) override {}
+ size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) override {
+ std::lock_guard<std::mutex> guard(mEventLock);
+ for (size_t i = 0; i < mCount; i++) buffer[i] = mBuf[i];
+
+ return mCount;
+ }
+ std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override { return mVideoFrames; }
+ int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override {
+ return fdp->ConsumeIntegral<int32_t>();
+ }
+ int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override {
+ return fdp->ConsumeIntegral<int32_t>();
+ }
+ int32_t getSwitchState(int32_t deviceId, int32_t sw) const override {
+ return fdp->ConsumeIntegral<int32_t>();
+ }
+ status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
+ int32_t* outValue) const override {
+ return fdp->ConsumeIntegral<status_t>();
+ }
+ bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
+ uint8_t* outFlags) const override {
+ return fdp->ConsumeBool();
+ }
+ bool hasScanCode(int32_t deviceId, int32_t scanCode) const override {
+ return fdp->ConsumeBool();
+ }
+ bool hasLed(int32_t deviceId, int32_t led) const override { return fdp->ConsumeBool(); }
+ void setLedState(int32_t deviceId, int32_t led, bool on) override {}
+ void getVirtualKeyDefinitions(
+ int32_t deviceId, std::vector<VirtualKeyDefinition>& outVirtualKeys) const override {}
+ sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const override { return nullptr; }
+ bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) override {
+ return fdp->ConsumeBool();
+ }
+ void vibrate(int32_t deviceId, nsecs_t duration) override {}
+ void cancelVibrate(int32_t deviceId) override {}
+ void requestReopenDevices() override {}
+ void wake() override {}
+ void dump(std::string& dump) override {}
+ void monitor() override {}
+ bool isDeviceEnabled(int32_t deviceId) override { return fdp->ConsumeBool(); }
+ status_t enableDevice(int32_t deviceId) override { return fdp->ConsumeIntegral<status_t>(); }
+ status_t disableDevice(int32_t deviceId) override { return fdp->ConsumeIntegral<status_t>(); }
+};
+
+class FuzzPointerController : public PointerControllerInterface {
+ std::shared_ptr<FuzzedDataProvider> fdp;
+
+public:
+ FuzzPointerController(std::shared_ptr<FuzzedDataProvider> fdp) : fdp(fdp) {}
+ ~FuzzPointerController() {}
+ bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const override {
+ return fdp->ConsumeBool();
+ }
+ void move(float deltaX, float deltaY) override {}
+ void setButtonState(int32_t buttonState) override {}
+ int32_t getButtonState() const override { return fdp->ConsumeIntegral<int32_t>(); }
+ void setPosition(float x, float y) override {}
+ void getPosition(float* outX, float* outY) const override {}
+ void fade(Transition transition) override {}
+ void unfade(Transition transition) override {}
+ void setPresentation(Presentation presentation) override {}
+ void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
+ BitSet32 spotIdBits, int32_t displayId) override {}
+ void clearSpots() override {}
+ int32_t getDisplayId() const override { return fdp->ConsumeIntegral<int32_t>(); }
+ void setDisplayViewport(const DisplayViewport& displayViewport) override {}
+};
+
+class FuzzInputReaderPolicy : public InputReaderPolicyInterface {
+ TouchAffineTransformation mTransform;
+ std::shared_ptr<FuzzPointerController> mPointerController;
+ std::shared_ptr<FuzzedDataProvider> fdp;
+
+protected:
+ ~FuzzInputReaderPolicy() {}
+
+public:
+ FuzzInputReaderPolicy(std::shared_ptr<FuzzedDataProvider> fdp) : fdp(fdp) {
+ mPointerController = std::make_shared<FuzzPointerController>(fdp);
+ }
+ void getReaderConfiguration(InputReaderConfiguration* outConfig) override {}
+ std::shared_ptr<PointerControllerInterface> obtainPointerController(int32_t deviceId) override {
+ return mPointerController;
+ }
+ void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override {}
+ sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier) override {
+ return nullptr;
+ }
+ std::string getDeviceAlias(const InputDeviceIdentifier& identifier) {
+ return fdp->ConsumeRandomLengthString(32);
+ }
+ TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
+ int32_t surfaceRotation) override {
+ return mTransform;
+ }
+ void setTouchAffineTransformation(const TouchAffineTransformation t) { mTransform = t; }
+};
+
+class FuzzInputListener : public virtual InputListenerInterface {
+protected:
+ ~FuzzInputListener() {}
+
+public:
+ FuzzInputListener() {}
+ void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) override {}
+ void notifyKey(const NotifyKeyArgs* args) override {}
+ void notifyMotion(const NotifyMotionArgs* args) override {}
+ void notifySwitch(const NotifySwitchArgs* args) override {}
+ void notifyDeviceReset(const NotifyDeviceResetArgs* args) override {}
+};
+
+class FuzzInputReaderContext : public InputReaderContext {
+ std::shared_ptr<EventHubInterface> mEventHub;
+ sp<InputReaderPolicyInterface> mPolicy;
+ sp<InputListenerInterface> mListener;
+ std::shared_ptr<FuzzedDataProvider> fdp;
+
+public:
+ FuzzInputReaderContext(std::shared_ptr<EventHubInterface> eventHub,
+ const sp<InputReaderPolicyInterface>& policy,
+ const sp<InputListenerInterface>& listener,
+ std::shared_ptr<FuzzedDataProvider> fdp)
+ : mEventHub(eventHub), mPolicy(policy), mListener(listener), fdp(fdp) {}
+ ~FuzzInputReaderContext() {}
+ void updateGlobalMetaState() override {}
+ int32_t getGlobalMetaState() { return fdp->ConsumeIntegral<int32_t>(); }
+ void disableVirtualKeysUntil(nsecs_t time) override {}
+ bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) override {
+ return fdp->ConsumeBool();
+ }
+ void fadePointer() override {}
+ std::shared_ptr<PointerControllerInterface> getPointerController(int32_t deviceId) override {
+ return mPolicy->obtainPointerController(0);
+ }
+ void requestTimeoutAtTime(nsecs_t when) override {}
+ int32_t bumpGeneration() override { return fdp->ConsumeIntegral<int32_t>(); }
+ void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) override {}
+ void dispatchExternalStylusState(const StylusState& outState) override {}
+ InputReaderPolicyInterface* getPolicy() override { return mPolicy.get(); }
+ InputListenerInterface* getListener() override { return mListener.get(); }
+ EventHubInterface* getEventHub() override { return mEventHub.get(); }
+ int32_t getNextId() override { return fdp->ConsumeIntegral<int32_t>(); }
+};
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
new file mode 100644
index 0000000..336ecb6
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2020 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 <FuzzContainer.h>
+#include <MultiTouchInputMapper.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+void addProperty(FuzzContainer& fuzzer, std::shared_ptr<FuzzedDataProvider> fdp) {
+ // Pick a random property to set for the mapper to have set.
+ fdp->PickValueInArray<std::function<void()>>(
+ {[&]() -> void {
+ fuzzer.addProperty(String8("touch.deviceType"), String8("touchScreen"));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.deviceType"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.size.scale"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.size.bias"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.size.isSummed"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.size.calibration"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.pressure.scale"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.size.calibration"),
+ fdp->ConsumeBool() ? String8("diameter") : String8("area"));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.pressure.calibration"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ }})();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+ std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+ FuzzContainer fuzzer = FuzzContainer(fdp);
+
+ MultiTouchInputMapper& mapper = fuzzer.getMapper<MultiTouchInputMapper>();
+ auto policyConfig = fuzzer.getPolicyConfig();
+
+ // Loop through mapper operations until randomness is exhausted.
+ while (fdp->remaining_bytes() > 0) {
+ fdp->PickValueInArray<std::function<void()>>({
+ [&]() -> void { addProperty(fuzzer, fdp); },
+ [&]() -> void {
+ std::string dump;
+ mapper.dump(dump);
+ },
+ [&]() -> void {
+ InputDeviceInfo info;
+ mapper.populateDeviceInfo(&info);
+ },
+ [&]() -> void { mapper.getSources(); },
+ [&]() -> void {
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+ fdp->ConsumeIntegral<uint32_t>());
+ },
+ [&]() -> void { mapper.reset(fdp->ConsumeIntegral<nsecs_t>()); },
+ [&]() -> void {
+ RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ mapper.process(&rawEvent);
+ },
+ [&]() -> void {
+ mapper.getKeyCodeState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ mapper.getScanCodeState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ mapper.markSupportedKeyCodes(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<size_t>(), nullptr, nullptr);
+ },
+ [&]() -> void { mapper.cancelTouch(fdp->ConsumeIntegral<nsecs_t>()); },
+ [&]() -> void { mapper.timeoutExpired(fdp->ConsumeIntegral<nsecs_t>()); },
+ [&]() -> void {
+ StylusState state{fdp->ConsumeIntegral<nsecs_t>(),
+ fdp->ConsumeFloatingPoint<float>(),
+ fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ mapper.updateExternalStylusState(state);
+ },
+ [&]() -> void { mapper.getAssociatedDisplayId(); },
+ })();
+ }
+
+ return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/SwitchInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/SwitchInputFuzzer.cpp
new file mode 100644
index 0000000..ae7429c
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/SwitchInputFuzzer.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020 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 <FuzzContainer.h>
+#include <SwitchInputMapper.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+ std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+ FuzzContainer fuzzer = FuzzContainer(fdp);
+
+ SwitchInputMapper& mapper = fuzzer.getMapper<SwitchInputMapper>();
+ auto policyConfig = fuzzer.getPolicyConfig();
+
+ // Loop through mapper operations until randomness is exhausted.
+ while (fdp->remaining_bytes() > 0) {
+ fdp->PickValueInArray<std::function<void()>>({
+ [&]() -> void {
+ std::string dump;
+ mapper.dump(dump);
+ },
+ [&]() -> void { mapper.getSources(); },
+ [&]() -> void {
+ RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ mapper.process(&rawEvent);
+ },
+ [&]() -> void {
+ mapper.getSwitchState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ })();
+ }
+
+ return 0;
+}
+
+} // namespace android