diff options
author | Rob Carr <racarr@google.com> | 2022-04-05 22:14:02 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2022-04-05 22:14:02 +0000 |
commit | dbdd2e6c11ca3653b7fd140df6eb9d966a9e2d37 (patch) | |
tree | 7eb986f5a24d492374f09523eaee40811ef38f2f | |
parent | 81061238c19d7ebabb453697a8c643324cf6c68e (diff) | |
parent | ade0d07ba1ae18d9aee25b22ff6ef49599217f67 (diff) | |
download | native-dbdd2e6c11ca3653b7fd140df6eb9d966a9e2d37.tar.gz |
Merge "DO NOT MERGE: SurfaceFlinger: Add Transaction#sanitize" into sc-v2-dev
-rw-r--r-- | libs/gui/LayerState.cpp | 65 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 8 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerState.h | 7 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 8 |
4 files changed, 87 insertions, 1 deletions
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 77a883b332..bf275a5900 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -391,6 +391,71 @@ void DisplayState::merge(const DisplayState& other) { } } +void layer_state_t::sanitize(int32_t permissions) { + // TODO: b/109894387 + // + // SurfaceFlinger's renderer is not prepared to handle cropping in the face of arbitrary + // rotation. To see the problem observe that if we have a square parent, and a child + // of the same size, then we rotate the child 45 degrees around its center, the child + // must now be cropped to a non rectangular 8 sided region. + // + // Of course we can fix this in the future. For now, we are lucky, SurfaceControl is + // private API, and arbitrary rotation is used in limited use cases, for instance: + // - WindowManager only uses rotation in one case, which is on a top level layer in which + // cropping is not an issue. + // - Launcher, as a privileged app, uses this to transition an application to PiP + // (picture-in-picture) mode. + // + // However given that abuse of rotation matrices could lead to surfaces extending outside + // of cropped areas, we need to prevent non-root clients without permission + // ACCESS_SURFACE_FLINGER nor ROTATE_SURFACE_FLINGER + // (a.k.a. everyone except WindowManager / tests / Launcher) from setting non rectangle + // preserving transformations. + if (what & eMatrixChanged) { + if (!(permissions & Permission::ROTATE_SURFACE_FLINGER)) { + ui::Transform t; + t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); + if (!t.preserveRects()) { + what &= ~eMatrixChanged; + ALOGE("Stripped non rect preserving matrix in sanitize"); + } + } + } + + if (what & layer_state_t::eInputInfoChanged) { + if (!(permissions & Permission::ACCESS_SURFACE_FLINGER)) { + what &= ~eInputInfoChanged; + ALOGE("Stripped attempt to set eInputInfoChanged in sanitize"); + } + } + if (what & layer_state_t::eTrustedOverlayChanged) { + if (!(permissions & Permission::ACCESS_SURFACE_FLINGER)) { + what &= ~eTrustedOverlayChanged; + ALOGE("Stripped attempt to set eTrustedOverlay in sanitize"); + } + } + if (what & layer_state_t::eDropInputModeChanged) { + if (!(permissions & Permission::ACCESS_SURFACE_FLINGER)) { + what &= ~eDropInputModeChanged; + ALOGE("Stripped attempt to set eDropInputModeChanged in sanitize"); + } + } + if (what & layer_state_t::eFrameRateSelectionPriority) { + if (!(permissions & Permission::ACCESS_SURFACE_FLINGER)) { + what &= ~eFrameRateSelectionPriority; + ALOGE("Stripped attempt to set eFrameRateSelectionPriority in sanitize"); + } + } + if (what & layer_state_t::eFrameRateChanged) { + if (!ValidateFrameRate(frameRate, frameRateCompatibility, + changeFrameRateStrategy, + "layer_state_t::sanitize", + permissions & Permission::ACCESS_SURFACE_FLINGER)) { + what &= ~eFrameRateChanged; // logged in ValidateFrameRate + } + } +} + void layer_state_t::merge(const layer_state_t& other) { if (other.what & ePositionChanged) { what |= ePositionChanged; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 725ea6571d..4bcc9d56c8 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -551,6 +551,13 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) mListenerCallbacks = other.mListenerCallbacks; } +void SurfaceComposerClient::Transaction::sanitize() { + for (auto & [handle, composerState] : mComposerStates) { + composerState.state.sanitize(0 /* permissionMask */); + } + mInputWindowCommands.clear(); +} + std::unique_ptr<SurfaceComposerClient::Transaction> SurfaceComposerClient::Transaction::createFromParcel(const Parcel* parcel) { auto transaction = std::make_unique<Transaction>(); @@ -635,7 +642,6 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel if (composerState.read(*parcel) == BAD_VALUE) { return BAD_VALUE; } - composerStates[surfaceControlHandle] = composerState; } diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 03e4aacdbe..2a8d30d2da 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -61,6 +61,12 @@ struct client_cache_t { * Used to communicate layer information between SurfaceFlinger and its clients. */ struct layer_state_t { + enum Permission { + ACCESS_SURFACE_FLINGER = 0x1, + ROTATE_SURFACE_FLINGER = 0x2, + INTERNAL_SYSTEM_WINDOW = 0x4, + }; + enum { eLayerHidden = 0x01, // SURFACE_HIDDEN in SurfaceControl.java eLayerOpaque = 0x02, // SURFACE_OPAQUE @@ -128,6 +134,7 @@ struct layer_state_t { status_t read(const Parcel& input); bool hasBufferChanges() const; bool hasValidBuffer() const; + void sanitize(int32_t permissions); struct matrix22_t { float dsdx{0}; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 0d1d1a37bd..76b6d44fd2 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -590,6 +590,14 @@ public: void setAnimationTransaction(); void setEarlyWakeupStart(); void setEarlyWakeupEnd(); + + /** + * Strip the transaction of all permissioned requests, required when + * accepting transactions across process boundaries. + * + * TODO (b/213644870): Remove all permissioned things from Transaction + */ + void sanitize(); }; status_t clearLayerFrameStats(const sp<IBinder>& token) const; |