diff options
author | 2025-02-18 04:12:31 -0800 | |
---|---|---|
committer | 2025-02-18 04:12:31 -0800 | |
commit | 01884db1d16616727cdfc4c0fa0ff3bc91e3e147 (patch) | |
tree | fd5db198915ad411b6bf3844ba64fb66738b0989 | |
parent | 43a1d490549ede9c1278b04484f43a9acbeb535e (diff) | |
parent | f54ab06b547439bcd03c58fd5d3f52a42f84c3d4 (diff) |
Merge changes I7c2108a2,I23fa0e50,I20d02933 into main
* changes:
inputflinger: Restricted invalid MotionEvent button enum values
inputflinger: Restricted invalid InputDeviceClass enum values
inputflinger: only use UTF-8 characters in device name and location
-rw-r--r-- | include/android/input.h | 2 | ||||
-rw-r--r-- | services/inputflinger/reader/include/EventHub.h | 2 | ||||
-rw-r--r-- | services/inputflinger/tests/fuzzers/FuzzedInputStream.h | 18 | ||||
-rw-r--r-- | services/inputflinger/tests/fuzzers/MapperHelpers.h | 34 | ||||
-rw-r--r-- | services/inputflinger/tests/fuzzers/ThreadSafeFuzzedDataProvider.h | 40 |
5 files changed, 85 insertions, 11 deletions
diff --git a/include/android/input.h b/include/android/input.h index 5f445509fa..2f6c5b57ff 100644 --- a/include/android/input.h +++ b/include/android/input.h @@ -862,7 +862,7 @@ enum { AMOTION_EVENT_BUTTON_FORWARD = 1 << 4, AMOTION_EVENT_BUTTON_STYLUS_PRIMARY = 1 << 5, AMOTION_EVENT_BUTTON_STYLUS_SECONDARY = 1 << 6, - // LINT.ThenChange(/frameworks/native/libs/input/rust/input.rs) + // LINT.ThenChange(/frameworks/native/libs/input/rust/input.rs,/frameworks/native/services/inputflinger/tests/fuzzers/FuzzedInputStream.h) }; /** diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h index 5dce074600..adbfdebfb0 100644 --- a/services/inputflinger/reader/include/EventHub.h +++ b/services/inputflinger/reader/include/EventHub.h @@ -88,6 +88,7 @@ std::ostream& operator<<(std::ostream& out, const std::optional<RawAbsoluteAxisI * If any new classes are added, we need to add them in rust input side too. */ enum class InputDeviceClass : uint32_t { + // LINT.IfChange /* The input device is a keyboard or has buttons. */ KEYBOARD = android::os::IInputConstants::DEVICE_CLASS_KEYBOARD, @@ -144,6 +145,7 @@ enum class InputDeviceClass : uint32_t { /* The input device is external (not built-in). */ EXTERNAL = android::os::IInputConstants::DEVICE_CLASS_EXTERNAL, + // LINT.ThenChange(frameworks/native/services/inputflinger/tests/fuzzers/MapperHelpers.h) }; enum class SysfsClass : uint32_t { diff --git a/services/inputflinger/tests/fuzzers/FuzzedInputStream.h b/services/inputflinger/tests/fuzzers/FuzzedInputStream.h index 767f9cdfa7..43975f0836 100644 --- a/services/inputflinger/tests/fuzzers/FuzzedInputStream.h +++ b/services/inputflinger/tests/fuzzers/FuzzedInputStream.h @@ -21,6 +21,14 @@ namespace android { static constexpr int32_t MAX_RANDOM_POINTERS = 4; static constexpr int32_t MAX_RANDOM_DEVICES = 4; +// The maximum value that we use for the action button field of NotifyMotionArgs. (We allow multiple +// bits to be set for this since we're just trying to generate a fuzzed event stream that doesn't +// cause crashes when enum values are converted to Rust — we don't necessarily want it to be valid.) +// +// AMOTION_EVENT_BUTTON_STYLUS_SECONDARY should be replaced with whatever AMOTION_EVENT_BUTTON_ +// value is highest if the enum is edited. +static constexpr int8_t MAX_ACTION_BUTTON_VALUE = (AMOTION_EVENT_BUTTON_STYLUS_SECONDARY << 1) - 1; + int getFuzzedMotionAction(FuzzedDataProvider& fdp) { int actionMasked = fdp.PickValueInArray<int>({ AMOTION_EVENT_ACTION_DOWN, AMOTION_EVENT_ACTION_UP, AMOTION_EVENT_ACTION_MOVE, @@ -185,18 +193,16 @@ NotifyMotionArgs generateFuzzedMotionArgs(IdGenerator& idGenerator, FuzzedDataPr fdp.ConsumeIntegralInRange<nsecs_t>(currentTime - 5E9, currentTime + 5E9); const nsecs_t readTime = downTime; const nsecs_t eventTime = fdp.ConsumeIntegralInRange<nsecs_t>(downTime, downTime + 1E9); + const int32_t actionButton = fdp.ConsumeIntegralInRange<int32_t>(0, MAX_ACTION_BUTTON_VALUE); const float cursorX = fdp.ConsumeIntegralInRange<int>(-10000, 10000); const float cursorY = fdp.ConsumeIntegralInRange<int>(-10000, 10000); return NotifyMotionArgs(idGenerator.nextId(), eventTime, readTime, deviceId, source, displayId, - POLICY_FLAG_PASS_TO_USER, action, - /*actionButton=*/fdp.ConsumeIntegral<int32_t>(), + POLICY_FLAG_PASS_TO_USER, action, actionButton, getFuzzedFlags(fdp, action), AMETA_NONE, getFuzzedButtonState(fdp), MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, pointerCount, - pointerProperties.data(), pointerCoords.data(), - /*xPrecision=*/0, - /*yPrecision=*/0, cursorX, cursorY, downTime, - /*videoFrames=*/{}); + pointerProperties.data(), pointerCoords.data(), /*xPrecision=*/0, + /*yPrecision=*/0, cursorX, cursorY, downTime, /*videoFrames=*/{}); } } // namespace android diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h index 846260a946..bba7389eed 100644 --- a/services/inputflinger/tests/fuzzers/MapperHelpers.h +++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h @@ -34,6 +34,28 @@ constexpr size_t kValidTypes[] = {EV_SW, android::EventHubInterface::DEVICE_ADDED, android::EventHubInterface::DEVICE_REMOVED}; +static const android::InputDeviceClass kInputDeviceClasses[] = { + android::InputDeviceClass::KEYBOARD, + android::InputDeviceClass::ALPHAKEY, + android::InputDeviceClass::TOUCH, + android::InputDeviceClass::CURSOR, + android::InputDeviceClass::TOUCH_MT, + android::InputDeviceClass::DPAD, + android::InputDeviceClass::GAMEPAD, + android::InputDeviceClass::SWITCH, + android::InputDeviceClass::JOYSTICK, + android::InputDeviceClass::VIBRATOR, + android::InputDeviceClass::MIC, + android::InputDeviceClass::EXTERNAL_STYLUS, + android::InputDeviceClass::ROTARY_ENCODER, + android::InputDeviceClass::SENSOR, + android::InputDeviceClass::BATTERY, + android::InputDeviceClass::LIGHT, + android::InputDeviceClass::TOUCHPAD, + android::InputDeviceClass::VIRTUAL, + android::InputDeviceClass::EXTERNAL, +}; + constexpr size_t kValidCodes[] = { SYN_REPORT, ABS_MT_SLOT, @@ -105,7 +127,13 @@ public: void addProperty(std::string key, std::string value) { mFuzzConfig.addProperty(key, value); } ftl::Flags<InputDeviceClass> getDeviceClasses(int32_t deviceId) const override { - return ftl::Flags<InputDeviceClass>(mFdp->ConsumeIntegral<uint32_t>()); + uint32_t flags = 0; + for (auto inputDeviceClass : kInputDeviceClasses) { + if (mFdp->ConsumeBool()) { + flags |= static_cast<uint32_t>(inputDeviceClass); + } + } + return ftl::Flags<InputDeviceClass>(flags); } InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const override { return mIdentifier; @@ -367,8 +395,8 @@ private: template <class Fdp> InputDevice getFuzzedInputDevice(Fdp& fdp, FuzzInputReaderContext* context) { InputDeviceIdentifier identifier; - identifier.name = fdp.ConsumeRandomLengthString(16); - identifier.location = fdp.ConsumeRandomLengthString(12); + identifier.name = fdp.ConsumeRandomLengthUtf8String(16); + identifier.location = fdp.ConsumeRandomLengthUtf8String(12); int32_t deviceID = fdp.ConsumeIntegralInRange(0, 5); int32_t deviceGeneration = fdp.ConsumeIntegralInRange(0, 5); return InputDevice(context, deviceID, deviceGeneration, identifier); diff --git a/services/inputflinger/tests/fuzzers/ThreadSafeFuzzedDataProvider.h b/services/inputflinger/tests/fuzzers/ThreadSafeFuzzedDataProvider.h index 2f76f181cb..b2581184e8 100644 --- a/services/inputflinger/tests/fuzzers/ThreadSafeFuzzedDataProvider.h +++ b/services/inputflinger/tests/fuzzers/ThreadSafeFuzzedDataProvider.h @@ -15,7 +15,7 @@ */ #include <fuzzer/FuzzedDataProvider.h> - +#include <algorithm> /** * A thread-safe interface to the FuzzedDataProvider */ @@ -60,6 +60,44 @@ public: return FuzzedDataProvider::ConsumeRandomLengthString(); } + // Converting the string to a UTF-8 string by setting the prefix bits of each + // byte according to UTF-8 encoding rules. + std::string ConsumeRandomLengthUtf8String(size_t max_length) { + std::scoped_lock _l(mLock); + std::string result = FuzzedDataProvider::ConsumeRandomLengthString(max_length); + size_t remaining_bytes = result.length(), idx = 0; + while (remaining_bytes > 0) { + size_t random_byte_size = FuzzedDataProvider::ConsumeIntegralInRange(1, 4); + size_t byte_size = std::min(random_byte_size, remaining_bytes); + switch (byte_size) { + // Prefix byte: 0xxxxxxx + case 1: + result[idx++] &= 0b01111111; + break; + // Prefix bytes: 110xxxxx 10xxxxxx + case 2: + result[idx++] = (result[idx] & 0b00011111) | 0b11000000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + break; + // Prefix bytes: 1110xxxx 10xxxxxx 10xxxxxx + case 3: + result[idx++] = (result[idx] & 0b00001111) | 0b11100000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + break; + // Prefix bytes: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + case 4: + result[idx++] = (result[idx] & 0b00000111) | 0b11110000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + break; + } + remaining_bytes -= byte_size; + } + return result; + } + std::string ConsumeRemainingBytesAsString() { std::scoped_lock _l(mLock); return FuzzedDataProvider::ConsumeRemainingBytesAsString(); |