diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-07 11:06:00 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-07 11:06:00 +0000 |
commit | 88e2e8c7a798df916a7ef6d0e34b09e9b9a5720e (patch) | |
tree | c7fa12f6bcf0896a2310f4587551ed2e310c4384 | |
parent | 4a1406e69501b77bdaaf9b204a5410883e7a008e (diff) | |
parent | f2d5b2a2da277d3f4dbcb81a8e3d71d76457740a (diff) | |
download | native-android-mainline-12.0.0_r118.tar.gz |
Snap for 8417617 from f2d5b2a2da277d3f4dbcb81a8e3d71d76457740a to mainline-ipsec-releaseandroid-mainline-12.0.0_r118
Change-Id: Ia10675203fd3ac20a9e5f5c1a0b5a6dafe1c99db
-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 2f31fbbb68..bb4b44684f 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -381,6 +381,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 6ffd25d227..3f1277ed57 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -527,6 +527,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>(); @@ -611,7 +618,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 feef343748..9460319f4b 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -63,6 +63,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 @@ -130,6 +136,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 6e17212911..4b2075082c 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -587,6 +587,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; |