diff options
author | 2024-08-02 12:10:05 -0700 | |
---|---|---|
committer | 2024-08-02 20:25:42 +0000 | |
commit | 9d0d65e174e7fe5fe9dea9474b5297ef1e5761bf (patch) | |
tree | 551836ffffed10f8ac3d044edd048ef31435bce3 | |
parent | 9b4b490937f1194bdfc5960ab54517c727ae3b51 (diff) |
Reject invalid events injected by accessibility
This will avoid the processing of inconsistent event streams inside
dispatcher, which can lead to crashes. Going forward, we should reject
all inconsistent injected events, not just those from a11y.
Bug: 356662669
Flag: EXEMPT bugfix
Test: TEST=inputflinger_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST --gtest_filter="*InvalidA11yEventsGetRejected"
Change-Id: Ia127bcedf2288a2522d33d046fbbc8eb389babfb
-rw-r--r-- | include/input/InputEventBuilders.h | 16 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 4 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 48 |
3 files changed, 61 insertions, 7 deletions
diff --git a/include/input/InputEventBuilders.h b/include/input/InputEventBuilders.h index 25d35e9fe7..55e058332d 100644 --- a/include/input/InputEventBuilders.h +++ b/include/input/InputEventBuilders.h @@ -127,7 +127,7 @@ public: return *this; } - MotionEvent build() { + MotionEvent build() const { std::vector<PointerProperties> pointerProperties; std::vector<PointerCoords> pointerCoords; for (const PointerBuilder& pointer : mPointers) { @@ -135,20 +135,22 @@ public: pointerCoords.push_back(pointer.buildCoords()); } + auto [xCursorPosition, yCursorPosition] = + std::make_pair(mRawXCursorPosition, mRawYCursorPosition); // Set mouse cursor position for the most common cases to avoid boilerplate. if (mSource == AINPUT_SOURCE_MOUSE && - !MotionEvent::isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition)) { - mRawXCursorPosition = pointerCoords[0].getX(); - mRawYCursorPosition = pointerCoords[0].getY(); + !MotionEvent::isValidCursorPosition(xCursorPosition, yCursorPosition)) { + xCursorPosition = pointerCoords[0].getX(); + yCursorPosition = pointerCoords[0].getY(); } MotionEvent event; event.initialize(InputEvent::nextId(), mDeviceId, mSource, mDisplayId, INVALID_HMAC, mAction, mActionButton, mFlags, /*edgeFlags=*/0, AMETA_NONE, mButtonState, MotionClassification::NONE, mTransform, - /*xPrecision=*/0, /*yPrecision=*/0, mRawXCursorPosition, - mRawYCursorPosition, mRawTransform, mDownTime, mEventTime, - mPointers.size(), pointerProperties.data(), pointerCoords.data()); + /*xPrecision=*/0, /*yPrecision=*/0, xCursorPosition, yCursorPosition, + mRawTransform, mDownTime, mEventTime, mPointers.size(), + pointerProperties.data(), pointerCoords.data()); return event; } diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index af4a04d9eb..faafa50eb8 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -4879,6 +4879,10 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev logDispatchStateLocked(); LOG(ERROR) << "Inconsistent event: " << motionEvent << ", reason: " << result.error(); + if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) { + mLock.unlock(); + return InputEventInjectionResult::FAILED; + } } } diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index e5058507eb..d418a9b5ec 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -5037,6 +5037,54 @@ TEST_F_WITH_FLAGS(InputDispatcherTest, InvalidA11yHoverStreamDoesNotCrash, } /** + * Invalid events injected by input filter are rejected. + */ +TEST_F(InputDispatcherTest, InvalidA11yEventsGetRejected) { + std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); + sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window", + ui::LogicalDisplayId::DEFAULT); + + mDispatcher->setFocusedApplication(ui::LogicalDisplayId::DEFAULT, application); + + mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0}); + + // a11y sets 'POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY' policy flag during injection, so define + // a custom injection function here for convenience. + auto injectFromAccessibility = [&](int32_t action, float x, float y) { + MotionEvent event = MotionEventBuilder(action, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(0, ToolType::FINGER).x(x).y(y)) + .addFlag(AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT) + .build(); + return injectMotionEvent(*mDispatcher, event, 100ms, + InputEventInjectionSync::WAIT_FOR_RESULT, /*targetUid=*/{}, + POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_FILTERED | + POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY); + }; + + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectFromAccessibility(ACTION_DOWN, /*x=*/300, /*y=*/400)); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectFromAccessibility(ACTION_MOVE, /*x=*/310, /*y=*/420)); + window->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); + window->consumeMotionEvent(WithMotionAction(ACTION_MOVE)); + // finger is still down, so a new DOWN event should be rejected! + ASSERT_EQ(InputEventInjectionResult::FAILED, + injectFromAccessibility(ACTION_DOWN, /*x=*/340, /*y=*/410)); + + // if the gesture is correctly finished, new down event will succeed + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectFromAccessibility(ACTION_MOVE, /*x=*/320, /*y=*/430)); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectFromAccessibility(ACTION_UP, /*x=*/320, /*y=*/430)); + window->consumeMotionEvent(WithMotionAction(ACTION_MOVE)); + window->consumeMotionEvent(WithMotionAction(ACTION_UP)); + + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectFromAccessibility(ACTION_DOWN, /*x=*/350, /*y=*/460)); + window->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); +} + +/** * If mouse is hovering when the touch goes down, the hovering should be stopped via HOVER_EXIT. */ TEST_F(InputDispatcherTest, TouchDownAfterMouseHover_legacy) { |