diff options
| author | 2023-05-09 18:05:37 +0000 | |
|---|---|---|
| committer | 2023-05-09 18:05:37 +0000 | |
| commit | e2ba12e4e241ea2f2acf3ca4e68b34fc5579256b (patch) | |
| tree | f5c54eed9b34d565b8db422498ac69edcc96a0d5 /services | |
| parent | 4963163cda4c670abbebd5deb1c1d65ce876084f (diff) | |
| parent | eb7596b865f35d9498e8d1e0f4169018cf423736 (diff) | |
Merge "Cleaned up transaction sanitize calls" into udc-dev am: eb7596b865
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/22652584
Change-Id: Iaf9163dd707561a14f5b4e101890dec73f814b78
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'services')
7 files changed, 173 insertions, 90 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 3c55caf188..dfe8c72bca 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -110,6 +110,7 @@ #include <unordered_map> #include <vector> +#include <gui/LayerStatePermissions.h> #include <ui/DisplayIdentification.h> #include "BackgroundExecutor.h" #include "Client.h" @@ -4392,7 +4393,7 @@ bool SurfaceFlinger::applyTransactionsLocked(std::vector<TransactionState>& tran transaction.inputWindowCommands, transaction.desiredPresentTime, transaction.isAutoTimestamp, std::move(transaction.uncacheBufferIds), transaction.postTime, - transaction.permissions, transaction.hasListenerCallbacks, + transaction.hasListenerCallbacks, transaction.listenerCallbacks, transaction.originPid, transaction.originUid, transaction.id); } @@ -4471,24 +4472,27 @@ bool SurfaceFlinger::shouldLatchUnsignaled(const sp<Layer>& layer, const layer_s status_t SurfaceFlinger::setTransactionState( const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, - const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, - bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers, - bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, - uint64_t transactionId) { + InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, + const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks, + const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) { ATRACE_CALL(); - uint32_t permissions = - callingThreadHasUnscopedSurfaceFlingerAccess() ? - layer_state_t::Permission::ACCESS_SURFACE_FLINGER : 0; - // Avoid checking for rotation permissions if the caller already has ACCESS_SURFACE_FLINGER - // permissions. - if ((permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) || - callingThreadHasPermission(sRotateSurfaceFlinger)) { - permissions |= layer_state_t::Permission::ROTATE_SURFACE_FLINGER; + IPCThreadState* ipc = IPCThreadState::self(); + const int originPid = ipc->getCallingPid(); + const int originUid = ipc->getCallingUid(); + uint32_t permissions = LayerStatePermissions::getTransactionPermissions(originPid, originUid); + for (auto composerState : states) { + composerState.state.sanitize(permissions); } - if (callingThreadHasPermission(sInternalSystemWindow)) { - permissions |= layer_state_t::Permission::INTERNAL_SYSTEM_WINDOW; + for (DisplayState display : displays) { + display.sanitize(permissions); + } + + if (!inputWindowCommands.empty() && + (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) == 0) { + ALOGE("Only privileged callers are allowed to send input commands."); + inputWindowCommands.clear(); } if (flags & (eEarlyWakeupStart | eEarlyWakeupEnd)) { @@ -4504,10 +4508,6 @@ status_t SurfaceFlinger::setTransactionState( const int64_t postTime = systemTime(); - IPCThreadState* ipc = IPCThreadState::self(); - const int originPid = ipc->getCallingPid(); - const int originUid = ipc->getCallingUid(); - std::vector<uint64_t> uncacheBufferIds; uncacheBufferIds.reserve(uncacheBuffers.size()); for (const auto& uncacheBuffer : uncacheBuffers) { @@ -4554,12 +4554,11 @@ status_t SurfaceFlinger::setTransactionState( displays, flags, applyToken, - inputWindowCommands, + std::move(inputWindowCommands), desiredPresentTime, isAutoTimestamp, std::move(uncacheBufferIds), postTime, - permissions, hasListenerCallbacks, listenerCallbacks, originPid, @@ -4588,14 +4587,12 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector<uint64_t>& uncacheBufferIds, - const int64_t postTime, uint32_t permissions, - bool hasListenerCallbacks, + const int64_t postTime, bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, int originPid, int originUid, uint64_t transactionId) { uint32_t transactionFlags = 0; if (!mLayerLifecycleManagerEnabled) { for (DisplayState& display : displays) { - display.sanitize(permissions); transactionFlags |= setDisplayStateLocked(display); } } @@ -4612,12 +4609,12 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin if (mLegacyFrontEndEnabled) { clientStateFlags |= setClientStateLocked(frameTimelineInfo, resolvedState, desiredPresentTime, - isAutoTimestamp, postTime, permissions, transactionId); + isAutoTimestamp, postTime, transactionId); } else /*mLayerLifecycleManagerEnabled*/ { clientStateFlags |= updateLayerCallbacksAndStats(frameTimelineInfo, resolvedState, desiredPresentTime, isAutoTimestamp, - postTime, permissions, transactionId); + postTime, transactionId); } if ((flags & eAnimation) && resolvedState.state.surface) { if (const auto layer = LayerHandle::getLayer(resolvedState.state.surface)) { @@ -4634,12 +4631,7 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin } transactionFlags |= clientStateFlags; - - if (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) { - transactionFlags |= addInputWindowCommands(inputWindowCommands); - } else if (!inputWindowCommands.empty()) { - ALOGE("Only privileged callers are allowed to send input commands."); - } + transactionFlags |= addInputWindowCommands(inputWindowCommands); for (uint64_t uncacheBufferId : uncacheBufferIds) { mBufferIdsToUncache.push_back(uncacheBufferId); @@ -4676,7 +4668,6 @@ bool SurfaceFlinger::applyAndCommitDisplayTransactionStates( uint32_t transactionFlags = 0; for (auto& transaction : transactions) { for (DisplayState& display : transaction.displays) { - display.sanitize(transaction.permissions); transactionFlags |= setDisplayStateLocked(display); } } @@ -4775,10 +4766,8 @@ bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermis uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTimelineInfo, ResolvedComposerState& composerState, int64_t desiredPresentTime, bool isAutoTimestamp, - int64_t postTime, uint32_t permissions, - uint64_t transactionId) { + int64_t postTime, uint64_t transactionId) { layer_state_t& s = composerState.state; - s.sanitize(permissions); std::vector<ListenerCallbacks> filteredListeners; for (auto& listener : s.listeners) { @@ -5127,10 +5116,8 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f ResolvedComposerState& composerState, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, - uint32_t permissions, uint64_t transactionId) { layer_state_t& s = composerState.state; - s.sanitize(permissions); std::vector<ListenerCallbacks> filteredListeners; for (auto& listener : s.listeners) { @@ -5412,7 +5399,6 @@ void SurfaceFlinger::initializeDisplays() { const nsecs_t now = systemTime(); state.desiredPresentTime = now; state.postTime = now; - state.permissions = layer_state_t::ACCESS_SURFACE_FLINGER; state.originPid = mPid; state.originUid = static_cast<int>(getuid()); const uint64_t transactionId = (static_cast<uint64_t>(mPid) << 32) | mUniqueTransactionId++; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 8eaa1c7f09..d92ec7a3b6 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -511,7 +511,7 @@ private: status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, - const InputWindowCommands& inputWindowCommands, + InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks, @@ -732,14 +732,16 @@ private: /* * Transactions */ - bool applyTransactionState( - const FrameTimelineInfo& info, std::vector<ResolvedComposerState>& state, - Vector<DisplayState>& displays, uint32_t flags, - const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, - bool isAutoTimestamp, const std::vector<uint64_t>& uncacheBufferIds, - const int64_t postTime, uint32_t permissions, bool hasListenerCallbacks, - const std::vector<ListenerCallbacks>& listenerCallbacks, int originPid, int originUid, - uint64_t transactionId) REQUIRES(mStateLock); + bool applyTransactionState(const FrameTimelineInfo& info, + std::vector<ResolvedComposerState>& state, + Vector<DisplayState>& displays, uint32_t flags, + const InputWindowCommands& inputWindowCommands, + const int64_t desiredPresentTime, bool isAutoTimestamp, + const std::vector<uint64_t>& uncacheBufferIds, + const int64_t postTime, bool hasListenerCallbacks, + const std::vector<ListenerCallbacks>& listenerCallbacks, + int originPid, int originUid, uint64_t transactionId) + REQUIRES(mStateLock); // Flush pending transactions that were presented after desiredPresentTime. // For test only bool flushTransactionQueues(VsyncId) REQUIRES(kMainThreadContext); @@ -760,12 +762,11 @@ private: uint32_t setClientStateLocked(const FrameTimelineInfo&, ResolvedComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, - int64_t postTime, uint32_t permissions, uint64_t transactionId) - REQUIRES(mStateLock); + int64_t postTime, uint64_t transactionId) REQUIRES(mStateLock); uint32_t updateLayerCallbacksAndStats(const FrameTimelineInfo&, ResolvedComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, - int64_t postTime, uint32_t permissions, - uint64_t transactionId) REQUIRES(mStateLock); + int64_t postTime, uint64_t transactionId) + REQUIRES(mStateLock); uint32_t getTransactionFlags() const; // Sets the masked bits, and schedules a commit if needed. diff --git a/services/surfaceflinger/TransactionState.h b/services/surfaceflinger/TransactionState.h index 35c8b6c647..62a7dfd0f1 100644 --- a/services/surfaceflinger/TransactionState.h +++ b/services/surfaceflinger/TransactionState.h @@ -54,7 +54,7 @@ struct TransactionState { const Vector<DisplayState>& displayStates, uint32_t transactionFlags, const sp<IBinder>& applyToken, const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, - std::vector<uint64_t> uncacheBufferIds, int64_t postTime, uint32_t permissions, + std::vector<uint64_t> uncacheBufferIds, int64_t postTime, bool hasListenerCallbacks, std::vector<ListenerCallbacks> listenerCallbacks, int originPid, int originUid, uint64_t transactionId) : frameTimelineInfo(frameTimelineInfo), @@ -67,7 +67,6 @@ struct TransactionState { isAutoTimestamp(isAutoTimestamp), uncacheBufferIds(std::move(uncacheBufferIds)), postTime(postTime), - permissions(permissions), hasListenerCallbacks(hasListenerCallbacks), listenerCallbacks(listenerCallbacks), originPid(originPid), @@ -126,7 +125,6 @@ struct TransactionState { bool isAutoTimestamp; std::vector<uint64_t> uncacheBufferIds; int64_t postTime; - uint32_t permissions; bool hasListenerCallbacks; std::vector<ListenerCallbacks> listenerCallbacks; int originPid; diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp index 4a45eb5586..69e9a169e3 100644 --- a/services/surfaceflinger/tests/Credentials_test.cpp +++ b/services/surfaceflinger/tests/Credentials_test.cpp @@ -31,6 +31,7 @@ #include <utils/String8.h> #include <functional> #include "utils/ScreenshotUtils.h" +#include "utils/WindowInfosListenerUtils.h" namespace android { @@ -378,6 +379,58 @@ TEST_F(CredentialsTest, GetActiveColorModeBasicCorrectness) { ASSERT_NE(static_cast<ColorMode>(BAD_VALUE), colorMode); } +TEST_F(CredentialsTest, TransactionPermissionTest) { + WindowInfosListenerUtils windowInfosListenerUtils; + std::string name = "Test Layer"; + sp<IBinder> token = sp<BBinder>::make(); + WindowInfo windowInfo; + windowInfo.name = name; + windowInfo.token = token; + sp<SurfaceControl> surfaceControl = + mComposerClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eFXSurfaceBufferState); + const Rect crop(0, 0, 100, 100); + { + UIDFaker f(AID_SYSTEM); + Transaction() + .setLayerStack(surfaceControl, ui::DEFAULT_LAYER_STACK) + .show(surfaceControl) + .setLayer(surfaceControl, INT32_MAX - 1) + .setCrop(surfaceControl, crop) + .setInputWindowInfo(surfaceControl, windowInfo) + .apply(); + } + + // Called from non privileged process + Transaction().setTrustedOverlay(surfaceControl, true); + { + UIDFaker f(AID_SYSTEM); + auto windowIsPresentAndNotTrusted = [&](const std::vector<WindowInfo>& windowInfos) { + auto foundWindowInfo = + WindowInfosListenerUtils::findMatchingWindowInfo(windowInfo, windowInfos); + if (!foundWindowInfo) { + return false; + } + return !foundWindowInfo->inputConfig.test(WindowInfo::InputConfig::TRUSTED_OVERLAY); + }; + windowInfosListenerUtils.waitForWindowInfosPredicate(windowIsPresentAndNotTrusted); + } + + { + UIDFaker f(AID_SYSTEM); + Transaction().setTrustedOverlay(surfaceControl, true); + auto windowIsPresentAndTrusted = [&](const std::vector<WindowInfo>& windowInfos) { + auto foundWindowInfo = + WindowInfosListenerUtils::findMatchingWindowInfo(windowInfo, windowInfos); + if (!foundWindowInfo) { + return false; + } + return foundWindowInfo->inputConfig.test(WindowInfo::InputConfig::TRUSTED_OVERLAY); + }; + windowInfosListenerUtils.waitForWindowInfosPredicate(windowIsPresentAndTrusted); + } +} + } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/services/surfaceflinger/tests/WindowInfosListener_test.cpp b/services/surfaceflinger/tests/WindowInfosListener_test.cpp index 3f27360cb7..ad9a674456 100644 --- a/services/surfaceflinger/tests/WindowInfosListener_test.cpp +++ b/services/surfaceflinger/tests/WindowInfosListener_test.cpp @@ -20,11 +20,13 @@ #include <private/android_filesystem_config.h> #include <cstdint> #include <future> +#include "utils/WindowInfosListenerUtils.h" namespace android { using Transaction = SurfaceComposerClient::Transaction; using gui::DisplayInfo; using gui::WindowInfo; +constexpr auto findMatchingWindowInfo = WindowInfosListenerUtils::findMatchingWindowInfo; using WindowInfosPredicate = std::function<bool(const std::vector<WindowInfo>&)>; @@ -37,45 +39,14 @@ protected: void TearDown() override { seteuid(AID_ROOT); } - struct WindowInfosListener : public gui::WindowInfosListener { - public: - WindowInfosListener(WindowInfosPredicate predicate, std::promise<void>& promise) - : mPredicate(std::move(predicate)), mPromise(promise) {} - - void onWindowInfosChanged(const gui::WindowInfosUpdate& update) override { - if (mPredicate(update.windowInfos)) { - mPromise.set_value(); - } - } - - private: - WindowInfosPredicate mPredicate; - std::promise<void>& mPromise; - }; - sp<SurfaceComposerClient> mClient; + WindowInfosListenerUtils mWindowInfosListenerUtils; - bool waitForWindowInfosPredicate(WindowInfosPredicate predicate) { - std::promise<void> promise; - auto listener = sp<WindowInfosListener>::make(std::move(predicate), promise); - mClient->addWindowInfosListener(listener); - auto future = promise.get_future(); - bool satisfied = future.wait_for(std::chrono::seconds{1}) == std::future_status::ready; - mClient->removeWindowInfosListener(listener); - return satisfied; + bool waitForWindowInfosPredicate(const WindowInfosPredicate& predicate) { + return mWindowInfosListenerUtils.waitForWindowInfosPredicate(std::move(predicate)); } }; -const WindowInfo* findMatchingWindowInfo(const WindowInfo& targetWindowInfo, - const std::vector<WindowInfo>& windowInfos) { - for (const WindowInfo& windowInfo : windowInfos) { - if (windowInfo.token == targetWindowInfo.token) { - return &windowInfo; - } - } - return nullptr; -} - TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) { std::string name = "Test Layer"; sp<IBinder> token = sp<BBinder>::make(); diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp index dbb7c6ce63..6a641b3926 100644 --- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp @@ -386,7 +386,7 @@ public: transaction.applyToken, transaction.inputWindowCommands, transaction.desiredPresentTime, - transaction.isAutoTimestamp, {}, systemTime(), 0, + transaction.isAutoTimestamp, {}, systemTime(), mHasListenerCallbacks, mCallbacks, getpid(), static_cast<int>(getuid()), transaction.id); mFlinger.setTransactionStateInternal(transactionState); diff --git a/services/surfaceflinger/tests/utils/WindowInfosListenerUtils.h b/services/surfaceflinger/tests/utils/WindowInfosListenerUtils.h new file mode 100644 index 0000000000..8e28a75ed4 --- /dev/null +++ b/services/surfaceflinger/tests/utils/WindowInfosListenerUtils.h @@ -0,0 +1,74 @@ +/* + * Copyright 2023 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 <gtest/gtest.h> +#include <gui/SurfaceComposerClient.h> +#include <private/android_filesystem_config.h> +#include <cstdint> +#include <future> + +namespace android { +using Transaction = SurfaceComposerClient::Transaction; +using gui::DisplayInfo; +using gui::WindowInfo; + +using WindowInfosPredicate = std::function<bool(const std::vector<WindowInfo>&)>; + +class WindowInfosListenerUtils { +public: + WindowInfosListenerUtils() { mClient = sp<SurfaceComposerClient>::make(); } + + bool waitForWindowInfosPredicate(const WindowInfosPredicate& predicate) { + std::promise<void> promise; + auto listener = sp<WindowInfosListener>::make(std::move(predicate), promise); + mClient->addWindowInfosListener(listener); + auto future = promise.get_future(); + bool satisfied = future.wait_for(std::chrono::seconds{1}) == std::future_status::ready; + mClient->removeWindowInfosListener(listener); + return satisfied; + } + + static const WindowInfo* findMatchingWindowInfo(const WindowInfo& targetWindowInfo, + const std::vector<WindowInfo>& windowInfos) { + for (const WindowInfo& windowInfo : windowInfos) { + if (windowInfo.token == targetWindowInfo.token) { + return &windowInfo; + } + } + return nullptr; + } + +private: + struct WindowInfosListener : public gui::WindowInfosListener { + public: + WindowInfosListener(WindowInfosPredicate predicate, std::promise<void>& promise) + : mPredicate(std::move(predicate)), mPromise(promise) {} + + void onWindowInfosChanged(const gui::WindowInfosUpdate& update) override { + if (mPredicate(update.windowInfos)) { + mPromise.set_value(); + } + } + + private: + WindowInfosPredicate mPredicate; + std::promise<void>& mPromise; + }; + + sp<SurfaceComposerClient> mClient; +}; + +} // namespace android |