Loading services/inputflinger/tests/fuzzers/Android.bp +31 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ cc_defaults { ], shared_libs: [ "android.hardware.input.classifier@1.0", "android.hardware.input.processor-V1-ndk", "libbase", "libbinder", "libcutils", Loading Loading @@ -117,3 +118,33 @@ cc_fuzz { "SwitchInputFuzzer.cpp", ], } cc_fuzz { name: "inputflinger_input_reader_fuzzer", defaults: [ "inputflinger_fuzz_defaults", ], srcs: [ "InputReaderFuzzer.cpp", ], } cc_fuzz { name: "inputflinger_blocking_queue_fuzzer", defaults: [ "inputflinger_fuzz_defaults", ], srcs: [ "BlockingQueueFuzzer.cpp", ], } cc_fuzz { name: "inputflinger_input_classifier_fuzzer", defaults: [ "inputflinger_fuzz_defaults", ], srcs: [ "InputClassifierFuzzer.cpp", ], } services/inputflinger/tests/fuzzers/BlockingQueueFuzzer.cpp 0 → 100644 +69 −0 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. */ #include <fuzzer/FuzzedDataProvider.h> #include <thread> #include "BlockingQueue.h" // Chosen to be a number large enough for variation in fuzzer runs, but not consume too much memory. static constexpr size_t MAX_CAPACITY = 1024; namespace android { extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) { FuzzedDataProvider fdp(data, size); size_t capacity = fdp.ConsumeIntegralInRange<size_t>(1, MAX_CAPACITY); size_t filled = 0; BlockingQueue<int32_t> queue(capacity); while (fdp.remaining_bytes() > 0) { fdp.PickValueInArray<std::function<void()>>({ [&]() -> void { size_t numPushes = fdp.ConsumeIntegralInRange<size_t>(0, capacity + 1); for (size_t i = 0; i < numPushes; i++) { queue.push(fdp.ConsumeIntegral<int32_t>()); } filled = std::min(capacity, filled + numPushes); }, [&]() -> void { // Pops blocks if it is empty, so only pop up to num elements inserted. size_t numPops = fdp.ConsumeIntegralInRange<size_t>(0, filled); for (size_t i = 0; i < numPops; i++) { queue.pop(); } filled > numPops ? filled -= numPops : filled = 0; }, [&]() -> void { queue.clear(); filled = 0; }, [&]() -> void { int32_t eraseElement = fdp.ConsumeIntegral<int32_t>(); queue.erase([&](int32_t element) { if (element == eraseElement) { filled--; return true; } return false; }); }, })(); } return 0; } } // namespace android services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp 0 → 100644 +126 −0 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. */ #include <MapperHelpers.h> #include <fuzzer/FuzzedDataProvider.h> #include "InputCommonConverter.h" #include "InputProcessor.h" namespace android { static constexpr int32_t MAX_AXES = 64; // Used by two fuzz operations and a bit lengthy, so pulled out into a function. NotifyMotionArgs generateFuzzedMotionArgs(FuzzedDataProvider &fdp) { // Create a basic motion event for testing PointerProperties properties; properties.id = 0; properties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER; PointerCoords coords; coords.clear(); for (int32_t i = 0; i < fdp.ConsumeIntegralInRange<int32_t>(0, MAX_AXES); i++) { coords.setAxisValue(fdp.ConsumeIntegral<int32_t>(), fdp.ConsumeFloatingPoint<float>()); } const nsecs_t downTime = 2; const nsecs_t readTime = downTime + fdp.ConsumeIntegralInRange<nsecs_t>(0, 1E8); NotifyMotionArgs motionArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/, downTime /*eventTime*/, readTime, fdp.ConsumeIntegral<int32_t>() /*deviceId*/, AINPUT_SOURCE_ANY, ADISPLAY_ID_DEFAULT, fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/, AMOTION_EVENT_ACTION_DOWN, fdp.ConsumeIntegral<int32_t>() /*actionButton*/, fdp.ConsumeIntegral<int32_t>() /*flags*/, AMETA_NONE, fdp.ConsumeIntegral<int32_t>() /*buttonState*/, MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, 1 /*pointerCount*/, &properties, &coords, fdp.ConsumeFloatingPoint<float>() /*xPrecision*/, fdp.ConsumeFloatingPoint<float>() /*yPrecision*/, AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION, downTime, {} /*videoFrames*/); return motionArgs; } extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) { FuzzedDataProvider fdp(data, size); std::unique_ptr<FuzzInputListener> mFuzzListener = std::make_unique<FuzzInputListener>(); std::unique_ptr<InputProcessorInterface> mClassifier = std::make_unique<InputProcessor>(*mFuzzListener); while (fdp.remaining_bytes() > 0) { fdp.PickValueInArray<std::function<void()>>({ [&]() -> void { // SendToNextStage_NotifyConfigurationChangedArgs NotifyConfigurationChangedArgs args(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/, fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/); mClassifier->notifyConfigurationChanged(&args); }, [&]() -> void { // SendToNextStage_NotifyKeyArgs const nsecs_t eventTime = fdp.ConsumeIntegral<nsecs_t>(); const nsecs_t readTime = eventTime + fdp.ConsumeIntegralInRange<nsecs_t>(0, 1E8); NotifyKeyArgs keyArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/, eventTime, readTime, fdp.ConsumeIntegral<int32_t>() /*deviceId*/, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_DEFAULT, fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/, AKEY_EVENT_ACTION_DOWN, fdp.ConsumeIntegral<int32_t>() /*flags*/, AKEYCODE_HOME, fdp.ConsumeIntegral<int32_t>() /*scanCode*/, AMETA_NONE, fdp.ConsumeIntegral<nsecs_t>() /*downTime*/); mClassifier->notifyKey(&keyArgs); }, [&]() -> void { // SendToNextStage_NotifyMotionArgs NotifyMotionArgs motionArgs = generateFuzzedMotionArgs(fdp); mClassifier->notifyMotion(&motionArgs); }, [&]() -> void { // SendToNextStage_NotifySwitchArgs NotifySwitchArgs switchArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/, fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/, fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/, fdp.ConsumeIntegral<uint32_t>() /*switchValues*/, fdp.ConsumeIntegral<uint32_t>() /*switchMask*/); mClassifier->notifySwitch(&switchArgs); }, [&]() -> void { // SendToNextStage_NotifyDeviceResetArgs NotifyDeviceResetArgs resetArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/, fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/, fdp.ConsumeIntegral<int32_t>() /*deviceId*/); mClassifier->notifyDeviceReset(&resetArgs); }, [&]() -> void { // InputClassifierConverterTest const NotifyMotionArgs motionArgs = generateFuzzedMotionArgs(fdp); aidl::android::hardware::input::common::MotionEvent motionEvent = notifyMotionArgsToHalMotionEvent(motionArgs); }, })(); } return 0; } } // namespace android services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp 0 → 100644 +279 −0 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. */ #include <InputReader.h> #include <MapperHelpers.h> #include <fuzzer/FuzzedDataProvider.h> #include <input/InputDevice.h> #include <chrono> #include <thread> namespace android { constexpr InputDeviceSensorType kInputDeviceSensorType[] = { InputDeviceSensorType::ACCELEROMETER, InputDeviceSensorType::MAGNETIC_FIELD, InputDeviceSensorType::ORIENTATION, InputDeviceSensorType::GYROSCOPE, InputDeviceSensorType::LIGHT, InputDeviceSensorType::PRESSURE, InputDeviceSensorType::TEMPERATURE, InputDeviceSensorType::PROXIMITY, InputDeviceSensorType::GRAVITY, InputDeviceSensorType::LINEAR_ACCELERATION, InputDeviceSensorType::ROTATION_VECTOR, InputDeviceSensorType::RELATIVE_HUMIDITY, InputDeviceSensorType::AMBIENT_TEMPERATURE, InputDeviceSensorType::MAGNETIC_FIELD_UNCALIBRATED, InputDeviceSensorType::GAME_ROTATION_VECTOR, InputDeviceSensorType::GYROSCOPE_UNCALIBRATED, InputDeviceSensorType::SIGNIFICANT_MOTION, }; class FuzzInputReader : public InputReaderInterface { public: FuzzInputReader(std::shared_ptr<EventHubInterface> fuzzEventHub, const sp<InputReaderPolicyInterface>& fuzzPolicy, InputListenerInterface& fuzzListener) { reader = std::make_unique<InputReader>(fuzzEventHub, fuzzPolicy, fuzzListener); } void dump(std::string& dump) { reader->dump(dump); } void monitor() { reader->monitor(); } bool isInputDeviceEnabled(int32_t deviceId) { return reader->isInputDeviceEnabled(deviceId); } status_t start() { return reader->start(); } status_t stop() { return reader->stop(); } std::vector<InputDeviceInfo> getInputDevices() const { return reader->getInputDevices(); } int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask, int32_t scanCode) { return reader->getScanCodeState(deviceId, sourceMask, scanCode); } int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) { return reader->getKeyCodeState(deviceId, sourceMask, keyCode); } int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t sw) { return reader->getSwitchState(deviceId, sourceMask, sw); } void toggleCapsLockState(int32_t deviceId) { reader->toggleCapsLockState(deviceId); } bool hasKeys(int32_t deviceId, uint32_t sourceMask, const std::vector<int32_t>& keyCodes, uint8_t* outFlags) { return reader->hasKeys(deviceId, sourceMask, keyCodes, outFlags); } void requestRefreshConfiguration(uint32_t changes) { reader->requestRefreshConfiguration(changes); } void vibrate(int32_t deviceId, const VibrationSequence& sequence, ssize_t repeat, int32_t token) { reader->vibrate(deviceId, sequence, repeat, token); } void cancelVibrate(int32_t deviceId, int32_t token) { reader->cancelVibrate(deviceId, token); } bool isVibrating(int32_t deviceId) { return reader->isVibrating(deviceId); } std::vector<int32_t> getVibratorIds(int32_t deviceId) { return reader->getVibratorIds(deviceId); } std::optional<int32_t> getBatteryCapacity(int32_t deviceId) { return reader->getBatteryCapacity(deviceId); } std::optional<int32_t> getBatteryStatus(int32_t deviceId) { return reader->getBatteryStatus(deviceId); } std::vector<InputDeviceLightInfo> getLights(int32_t deviceId) { return reader->getLights(deviceId); } std::vector<InputDeviceSensorInfo> getSensors(int32_t deviceId) { return reader->getSensors(deviceId); } bool canDispatchToDisplay(int32_t deviceId, int32_t displayId) { return reader->canDispatchToDisplay(deviceId, displayId); } bool enableSensor(int32_t deviceId, InputDeviceSensorType sensorType, std::chrono::microseconds samplingPeriod, std::chrono::microseconds maxBatchReportLatency) { return reader->enableSensor(deviceId, sensorType, samplingPeriod, maxBatchReportLatency); } void disableSensor(int32_t deviceId, InputDeviceSensorType sensorType) { return reader->disableSensor(deviceId, sensorType); } void flushSensor(int32_t deviceId, InputDeviceSensorType sensorType) { return reader->flushSensor(deviceId, sensorType); } bool setLightColor(int32_t deviceId, int32_t lightId, int32_t color) { return reader->setLightColor(deviceId, lightId, color); } bool setLightPlayerId(int32_t deviceId, int32_t lightId, int32_t playerId) { return reader->setLightPlayerId(deviceId, lightId, playerId); } std::optional<int32_t> getLightColor(int32_t deviceId, int32_t lightId) { return reader->getLightColor(deviceId, lightId); } std::optional<int32_t> getLightPlayerId(int32_t deviceId, int32_t lightId) { return reader->getLightPlayerId(deviceId, lightId); } int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const { return reader->getKeyCodeForKeyLocation(deviceId, locationKeyCode); } private: std::unique_ptr<InputReaderInterface> reader; }; extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) { std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size); FuzzInputListener fuzzListener; sp<FuzzInputReaderPolicy> fuzzPolicy = sp<FuzzInputReaderPolicy>::make(fdp); std::shared_ptr<FuzzEventHub> fuzzEventHub = std::make_shared<FuzzEventHub>(fdp); std::unique_ptr<FuzzInputReader> reader = std::make_unique<FuzzInputReader>(fuzzEventHub, fuzzPolicy, fuzzListener); fuzzEventHub->addEvents(fdp); size_t patternCount = fdp->ConsumeIntegralInRange<size_t>(1, 260); VibrationSequence pattern(patternCount); for (size_t i = 0; i < patternCount; ++i) { VibrationElement element(i); element.addChannel(fdp->ConsumeIntegral<int32_t>() /* vibratorId */, fdp->ConsumeIntegral<uint8_t>() /* amplitude */); pattern.addElement(element); } reader->vibrate(fdp->ConsumeIntegral<int32_t>(), pattern, fdp->ConsumeIntegral<ssize_t>() /*repeat*/, fdp->ConsumeIntegral<int32_t>() /*token*/); reader->start(); // Loop through mapper operations until randomness is exhausted. while (fdp->remaining_bytes() > 0) { fdp->PickValueInArray<std::function<void()>>({ [&]() -> void { std::string dump; reader->dump(dump); }, [&]() -> void { reader->monitor(); }, [&]() -> void { reader->getInputDevices(); }, [&]() -> void { reader->isInputDeviceEnabled(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getScanCodeState(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<uint32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getKeyCodeState(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<uint32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getSwitchState(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<uint32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->toggleCapsLockState(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { size_t count = fdp->ConsumeIntegralInRange<size_t>(1, 1024); std::vector<uint8_t> outFlags(count); std::vector<int32_t> keyCodes; for (size_t i = 0; i < count; ++i) { keyCodes.push_back(fdp->ConsumeIntegral<int32_t>()); } reader->hasKeys(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<uint32_t>(), keyCodes, outFlags.data()); }, [&]() -> void { reader->requestRefreshConfiguration(fdp->ConsumeIntegral<uint32_t>()); }, [&]() -> void { reader->cancelVibrate(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->canDispatchToDisplay(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getKeyCodeForKeyLocation(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getBatteryCapacity(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getBatteryStatus(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getLights(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getSensors(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getLightPlayerId(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getLightColor(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->setLightPlayerId(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->setLightColor(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->flushSensor(fdp->ConsumeIntegral<int32_t>(), fdp->PickValueInArray<InputDeviceSensorType>( kInputDeviceSensorType)); }, [&]() -> void { reader->disableSensor(fdp->ConsumeIntegral<int32_t>(), fdp->PickValueInArray<InputDeviceSensorType>( kInputDeviceSensorType)); }, [&]() -> void { reader->enableSensor(fdp->ConsumeIntegral<int32_t>(), fdp->PickValueInArray<InputDeviceSensorType>( kInputDeviceSensorType), std::chrono::microseconds(fdp->ConsumeIntegral<size_t>()), std::chrono::microseconds(fdp->ConsumeIntegral<size_t>())); }, })(); } reader->stop(); return 0; } } // namespace android Loading
services/inputflinger/tests/fuzzers/Android.bp +31 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ cc_defaults { ], shared_libs: [ "android.hardware.input.classifier@1.0", "android.hardware.input.processor-V1-ndk", "libbase", "libbinder", "libcutils", Loading Loading @@ -117,3 +118,33 @@ cc_fuzz { "SwitchInputFuzzer.cpp", ], } cc_fuzz { name: "inputflinger_input_reader_fuzzer", defaults: [ "inputflinger_fuzz_defaults", ], srcs: [ "InputReaderFuzzer.cpp", ], } cc_fuzz { name: "inputflinger_blocking_queue_fuzzer", defaults: [ "inputflinger_fuzz_defaults", ], srcs: [ "BlockingQueueFuzzer.cpp", ], } cc_fuzz { name: "inputflinger_input_classifier_fuzzer", defaults: [ "inputflinger_fuzz_defaults", ], srcs: [ "InputClassifierFuzzer.cpp", ], }
services/inputflinger/tests/fuzzers/BlockingQueueFuzzer.cpp 0 → 100644 +69 −0 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. */ #include <fuzzer/FuzzedDataProvider.h> #include <thread> #include "BlockingQueue.h" // Chosen to be a number large enough for variation in fuzzer runs, but not consume too much memory. static constexpr size_t MAX_CAPACITY = 1024; namespace android { extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) { FuzzedDataProvider fdp(data, size); size_t capacity = fdp.ConsumeIntegralInRange<size_t>(1, MAX_CAPACITY); size_t filled = 0; BlockingQueue<int32_t> queue(capacity); while (fdp.remaining_bytes() > 0) { fdp.PickValueInArray<std::function<void()>>({ [&]() -> void { size_t numPushes = fdp.ConsumeIntegralInRange<size_t>(0, capacity + 1); for (size_t i = 0; i < numPushes; i++) { queue.push(fdp.ConsumeIntegral<int32_t>()); } filled = std::min(capacity, filled + numPushes); }, [&]() -> void { // Pops blocks if it is empty, so only pop up to num elements inserted. size_t numPops = fdp.ConsumeIntegralInRange<size_t>(0, filled); for (size_t i = 0; i < numPops; i++) { queue.pop(); } filled > numPops ? filled -= numPops : filled = 0; }, [&]() -> void { queue.clear(); filled = 0; }, [&]() -> void { int32_t eraseElement = fdp.ConsumeIntegral<int32_t>(); queue.erase([&](int32_t element) { if (element == eraseElement) { filled--; return true; } return false; }); }, })(); } return 0; } } // namespace android
services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp 0 → 100644 +126 −0 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. */ #include <MapperHelpers.h> #include <fuzzer/FuzzedDataProvider.h> #include "InputCommonConverter.h" #include "InputProcessor.h" namespace android { static constexpr int32_t MAX_AXES = 64; // Used by two fuzz operations and a bit lengthy, so pulled out into a function. NotifyMotionArgs generateFuzzedMotionArgs(FuzzedDataProvider &fdp) { // Create a basic motion event for testing PointerProperties properties; properties.id = 0; properties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER; PointerCoords coords; coords.clear(); for (int32_t i = 0; i < fdp.ConsumeIntegralInRange<int32_t>(0, MAX_AXES); i++) { coords.setAxisValue(fdp.ConsumeIntegral<int32_t>(), fdp.ConsumeFloatingPoint<float>()); } const nsecs_t downTime = 2; const nsecs_t readTime = downTime + fdp.ConsumeIntegralInRange<nsecs_t>(0, 1E8); NotifyMotionArgs motionArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/, downTime /*eventTime*/, readTime, fdp.ConsumeIntegral<int32_t>() /*deviceId*/, AINPUT_SOURCE_ANY, ADISPLAY_ID_DEFAULT, fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/, AMOTION_EVENT_ACTION_DOWN, fdp.ConsumeIntegral<int32_t>() /*actionButton*/, fdp.ConsumeIntegral<int32_t>() /*flags*/, AMETA_NONE, fdp.ConsumeIntegral<int32_t>() /*buttonState*/, MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, 1 /*pointerCount*/, &properties, &coords, fdp.ConsumeFloatingPoint<float>() /*xPrecision*/, fdp.ConsumeFloatingPoint<float>() /*yPrecision*/, AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION, downTime, {} /*videoFrames*/); return motionArgs; } extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) { FuzzedDataProvider fdp(data, size); std::unique_ptr<FuzzInputListener> mFuzzListener = std::make_unique<FuzzInputListener>(); std::unique_ptr<InputProcessorInterface> mClassifier = std::make_unique<InputProcessor>(*mFuzzListener); while (fdp.remaining_bytes() > 0) { fdp.PickValueInArray<std::function<void()>>({ [&]() -> void { // SendToNextStage_NotifyConfigurationChangedArgs NotifyConfigurationChangedArgs args(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/, fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/); mClassifier->notifyConfigurationChanged(&args); }, [&]() -> void { // SendToNextStage_NotifyKeyArgs const nsecs_t eventTime = fdp.ConsumeIntegral<nsecs_t>(); const nsecs_t readTime = eventTime + fdp.ConsumeIntegralInRange<nsecs_t>(0, 1E8); NotifyKeyArgs keyArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/, eventTime, readTime, fdp.ConsumeIntegral<int32_t>() /*deviceId*/, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_DEFAULT, fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/, AKEY_EVENT_ACTION_DOWN, fdp.ConsumeIntegral<int32_t>() /*flags*/, AKEYCODE_HOME, fdp.ConsumeIntegral<int32_t>() /*scanCode*/, AMETA_NONE, fdp.ConsumeIntegral<nsecs_t>() /*downTime*/); mClassifier->notifyKey(&keyArgs); }, [&]() -> void { // SendToNextStage_NotifyMotionArgs NotifyMotionArgs motionArgs = generateFuzzedMotionArgs(fdp); mClassifier->notifyMotion(&motionArgs); }, [&]() -> void { // SendToNextStage_NotifySwitchArgs NotifySwitchArgs switchArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/, fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/, fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/, fdp.ConsumeIntegral<uint32_t>() /*switchValues*/, fdp.ConsumeIntegral<uint32_t>() /*switchMask*/); mClassifier->notifySwitch(&switchArgs); }, [&]() -> void { // SendToNextStage_NotifyDeviceResetArgs NotifyDeviceResetArgs resetArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/, fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/, fdp.ConsumeIntegral<int32_t>() /*deviceId*/); mClassifier->notifyDeviceReset(&resetArgs); }, [&]() -> void { // InputClassifierConverterTest const NotifyMotionArgs motionArgs = generateFuzzedMotionArgs(fdp); aidl::android::hardware::input::common::MotionEvent motionEvent = notifyMotionArgsToHalMotionEvent(motionArgs); }, })(); } return 0; } } // namespace android
services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp 0 → 100644 +279 −0 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. */ #include <InputReader.h> #include <MapperHelpers.h> #include <fuzzer/FuzzedDataProvider.h> #include <input/InputDevice.h> #include <chrono> #include <thread> namespace android { constexpr InputDeviceSensorType kInputDeviceSensorType[] = { InputDeviceSensorType::ACCELEROMETER, InputDeviceSensorType::MAGNETIC_FIELD, InputDeviceSensorType::ORIENTATION, InputDeviceSensorType::GYROSCOPE, InputDeviceSensorType::LIGHT, InputDeviceSensorType::PRESSURE, InputDeviceSensorType::TEMPERATURE, InputDeviceSensorType::PROXIMITY, InputDeviceSensorType::GRAVITY, InputDeviceSensorType::LINEAR_ACCELERATION, InputDeviceSensorType::ROTATION_VECTOR, InputDeviceSensorType::RELATIVE_HUMIDITY, InputDeviceSensorType::AMBIENT_TEMPERATURE, InputDeviceSensorType::MAGNETIC_FIELD_UNCALIBRATED, InputDeviceSensorType::GAME_ROTATION_VECTOR, InputDeviceSensorType::GYROSCOPE_UNCALIBRATED, InputDeviceSensorType::SIGNIFICANT_MOTION, }; class FuzzInputReader : public InputReaderInterface { public: FuzzInputReader(std::shared_ptr<EventHubInterface> fuzzEventHub, const sp<InputReaderPolicyInterface>& fuzzPolicy, InputListenerInterface& fuzzListener) { reader = std::make_unique<InputReader>(fuzzEventHub, fuzzPolicy, fuzzListener); } void dump(std::string& dump) { reader->dump(dump); } void monitor() { reader->monitor(); } bool isInputDeviceEnabled(int32_t deviceId) { return reader->isInputDeviceEnabled(deviceId); } status_t start() { return reader->start(); } status_t stop() { return reader->stop(); } std::vector<InputDeviceInfo> getInputDevices() const { return reader->getInputDevices(); } int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask, int32_t scanCode) { return reader->getScanCodeState(deviceId, sourceMask, scanCode); } int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) { return reader->getKeyCodeState(deviceId, sourceMask, keyCode); } int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t sw) { return reader->getSwitchState(deviceId, sourceMask, sw); } void toggleCapsLockState(int32_t deviceId) { reader->toggleCapsLockState(deviceId); } bool hasKeys(int32_t deviceId, uint32_t sourceMask, const std::vector<int32_t>& keyCodes, uint8_t* outFlags) { return reader->hasKeys(deviceId, sourceMask, keyCodes, outFlags); } void requestRefreshConfiguration(uint32_t changes) { reader->requestRefreshConfiguration(changes); } void vibrate(int32_t deviceId, const VibrationSequence& sequence, ssize_t repeat, int32_t token) { reader->vibrate(deviceId, sequence, repeat, token); } void cancelVibrate(int32_t deviceId, int32_t token) { reader->cancelVibrate(deviceId, token); } bool isVibrating(int32_t deviceId) { return reader->isVibrating(deviceId); } std::vector<int32_t> getVibratorIds(int32_t deviceId) { return reader->getVibratorIds(deviceId); } std::optional<int32_t> getBatteryCapacity(int32_t deviceId) { return reader->getBatteryCapacity(deviceId); } std::optional<int32_t> getBatteryStatus(int32_t deviceId) { return reader->getBatteryStatus(deviceId); } std::vector<InputDeviceLightInfo> getLights(int32_t deviceId) { return reader->getLights(deviceId); } std::vector<InputDeviceSensorInfo> getSensors(int32_t deviceId) { return reader->getSensors(deviceId); } bool canDispatchToDisplay(int32_t deviceId, int32_t displayId) { return reader->canDispatchToDisplay(deviceId, displayId); } bool enableSensor(int32_t deviceId, InputDeviceSensorType sensorType, std::chrono::microseconds samplingPeriod, std::chrono::microseconds maxBatchReportLatency) { return reader->enableSensor(deviceId, sensorType, samplingPeriod, maxBatchReportLatency); } void disableSensor(int32_t deviceId, InputDeviceSensorType sensorType) { return reader->disableSensor(deviceId, sensorType); } void flushSensor(int32_t deviceId, InputDeviceSensorType sensorType) { return reader->flushSensor(deviceId, sensorType); } bool setLightColor(int32_t deviceId, int32_t lightId, int32_t color) { return reader->setLightColor(deviceId, lightId, color); } bool setLightPlayerId(int32_t deviceId, int32_t lightId, int32_t playerId) { return reader->setLightPlayerId(deviceId, lightId, playerId); } std::optional<int32_t> getLightColor(int32_t deviceId, int32_t lightId) { return reader->getLightColor(deviceId, lightId); } std::optional<int32_t> getLightPlayerId(int32_t deviceId, int32_t lightId) { return reader->getLightPlayerId(deviceId, lightId); } int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const { return reader->getKeyCodeForKeyLocation(deviceId, locationKeyCode); } private: std::unique_ptr<InputReaderInterface> reader; }; extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) { std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size); FuzzInputListener fuzzListener; sp<FuzzInputReaderPolicy> fuzzPolicy = sp<FuzzInputReaderPolicy>::make(fdp); std::shared_ptr<FuzzEventHub> fuzzEventHub = std::make_shared<FuzzEventHub>(fdp); std::unique_ptr<FuzzInputReader> reader = std::make_unique<FuzzInputReader>(fuzzEventHub, fuzzPolicy, fuzzListener); fuzzEventHub->addEvents(fdp); size_t patternCount = fdp->ConsumeIntegralInRange<size_t>(1, 260); VibrationSequence pattern(patternCount); for (size_t i = 0; i < patternCount; ++i) { VibrationElement element(i); element.addChannel(fdp->ConsumeIntegral<int32_t>() /* vibratorId */, fdp->ConsumeIntegral<uint8_t>() /* amplitude */); pattern.addElement(element); } reader->vibrate(fdp->ConsumeIntegral<int32_t>(), pattern, fdp->ConsumeIntegral<ssize_t>() /*repeat*/, fdp->ConsumeIntegral<int32_t>() /*token*/); reader->start(); // Loop through mapper operations until randomness is exhausted. while (fdp->remaining_bytes() > 0) { fdp->PickValueInArray<std::function<void()>>({ [&]() -> void { std::string dump; reader->dump(dump); }, [&]() -> void { reader->monitor(); }, [&]() -> void { reader->getInputDevices(); }, [&]() -> void { reader->isInputDeviceEnabled(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getScanCodeState(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<uint32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getKeyCodeState(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<uint32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getSwitchState(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<uint32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->toggleCapsLockState(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { size_t count = fdp->ConsumeIntegralInRange<size_t>(1, 1024); std::vector<uint8_t> outFlags(count); std::vector<int32_t> keyCodes; for (size_t i = 0; i < count; ++i) { keyCodes.push_back(fdp->ConsumeIntegral<int32_t>()); } reader->hasKeys(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<uint32_t>(), keyCodes, outFlags.data()); }, [&]() -> void { reader->requestRefreshConfiguration(fdp->ConsumeIntegral<uint32_t>()); }, [&]() -> void { reader->cancelVibrate(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->canDispatchToDisplay(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getKeyCodeForKeyLocation(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getBatteryCapacity(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getBatteryStatus(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getLights(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getSensors(fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getLightPlayerId(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->getLightColor(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->setLightPlayerId(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->setLightColor(fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>()); }, [&]() -> void { reader->flushSensor(fdp->ConsumeIntegral<int32_t>(), fdp->PickValueInArray<InputDeviceSensorType>( kInputDeviceSensorType)); }, [&]() -> void { reader->disableSensor(fdp->ConsumeIntegral<int32_t>(), fdp->PickValueInArray<InputDeviceSensorType>( kInputDeviceSensorType)); }, [&]() -> void { reader->enableSensor(fdp->ConsumeIntegral<int32_t>(), fdp->PickValueInArray<InputDeviceSensorType>( kInputDeviceSensorType), std::chrono::microseconds(fdp->ConsumeIntegral<size_t>()), std::chrono::microseconds(fdp->ConsumeIntegral<size_t>())); }, })(); } reader->stop(); return 0; } } // namespace android