diff options
| author | 2023-05-05 15:02:20 -0700 | |
|---|---|---|
| committer | 2023-06-10 00:20:43 +0000 | |
| commit | 580fb3af1743d2a6e12bd8c3f933641644e5eb4a (patch) | |
| tree | 9f499dea1f01de680ba87e732c0cb44094e116df | |
| parent | e632c7cbd2ee0483b48bd4924aff2ff1375a7b10 (diff) | |
Prevent targeted injection into non-owned windows
Before this CL, it was possible to send ACTION_OUTSIDE events to
non-owned windows even during targeted injection.
However:
1) It's not clear why we actually need this behaviour, and it requires
extra work to support this
2) The block of code that we used to "support" this didn't actually do
anything.
3) During targeted injection, you should only be allowed to affect owned
windows. If you want to affect the entire system, you:
a) Should use global rather than targeted injection
b) Must be very careful to clean up any remaining state that you
cause
In this CL, we remove the block of code that did nothing, and also add
an explicit target pass to remove any non-owned windows.
This should allow further future refactors.
Bug: 211379801
Fixes: 281091008
Test: m inputflinger_tests && $ANDROID_HOST_OUT/nativetest64/inputflinger_tests/inputflinger_tests
Change-Id: Ib065d39ab162188bf2f6e73601e2bb7e2c5d0409
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 19 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 6 |
2 files changed, 16 insertions, 9 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index f18265fe02..055fb6f9e3 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -2579,11 +2579,6 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( if (entry.injectionState != nullptr) { std::string errs; for (const TouchedWindow& touchedWindow : tempTouchState.windows) { - if (touchedWindow.targetFlags.test(InputTarget::Flags::DISPATCH_AS_OUTSIDE)) { - // Allow ACTION_OUTSIDE events generated by targeted injection to be - // dispatched to any uid, since the coords will be zeroed out later. - continue; - } const auto err = verifyTargetedInjection(touchedWindow.windowHandle, entry); if (err) errs += "\n - " + *err; } @@ -2636,6 +2631,18 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( targets); } + // During targeted injection, only allow owned targets to receive events + std::erase_if(targets, [&](const InputTarget& target) { + LOG_ALWAYS_FATAL_IF(target.windowHandle == nullptr); + const auto err = verifyTargetedInjection(target.windowHandle, entry); + if (err) { + LOG(WARNING) << "Dropping injected event from " << target.windowHandle->getName() + << ": " << (*err); + return true; + } + return false; + }); + if (targets.empty()) { LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription(); outInjectionResult = InputEventInjectionResult::FAILED; @@ -2838,7 +2845,7 @@ std::optional<InputTarget> InputDispatcher::createInputTargetLocked( if (displayInfoIt != mDisplayInfos.end()) { inputTarget.displayTransform = displayInfoIt->second.transform; } else { - // DisplayInfo not found for this window on display windowInfo->displayId. + // DisplayInfo not found for this window on display windowHandle->getInfo()->displayId. // TODO(b/198444055): Make this an error message after 'setInputWindows' API is removed. } return inputTarget; diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 92e7f431ab..8b74b2524d 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -9777,7 +9777,7 @@ TEST_F(InputDispatcherTargetedInjectionTest, CanInjectIntoAnyWindowWhenNotTarget window->assertNoEvents(); } -TEST_F(InputDispatcherTargetedInjectionTest, CanGenerateActionOutsideToOtherUids) { +TEST_F(InputDispatcherTargetedInjectionTest, CannotGenerateActionOutsideToOtherUids) { auto owner = User(mDispatcher, 10, 11); auto window = owner.createWindow(); @@ -9787,11 +9787,11 @@ TEST_F(InputDispatcherTargetedInjectionTest, CanGenerateActionOutsideToOtherUids randosWindow->setWatchOutsideTouch(true); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {randosWindow, window}}}); - // We allow generation of ACTION_OUTSIDE events into windows owned by different uids. + // Do not allow generation of ACTION_OUTSIDE events into windows owned by different uids. EXPECT_EQ(InputEventInjectionResult::SUCCEEDED, owner.injectTargetedMotion(AMOTION_EVENT_ACTION_DOWN)); window->consumeMotionDown(); - randosWindow->consumeMotionOutside(); + randosWindow->assertNoEvents(); } } // namespace android::inputdispatcher |