summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Mouri <alecmouri@google.com>2025-05-15 16:39:49 +0000
committeraoleary <seanm187@gmail.com>2025-10-07 19:01:35 +0000
commit3bb97db301463e83d1b1d42ebb1d5c130104d3e3 (patch)
tree679858f47deb87e1b00f0af60469950d007b8def
parent2087c1b260785789a88a511139d2fc1a0abec43a (diff)
Don't blur too many layerst13.0
An application requesting lots and lots of blurs: a. Enables pixel stealing by measuring how long it takes to perform a blur across windows b. Probably isn't very valid anyways. So, just arbitrarily pick an upper bound for blur requests that a display is allowed to manage (10), and disable everything else. Arbitrarily, pick the 10 "front-most" blurs to be respected. Bug: 399120953 Flag: EXEMPT security Test: Security PoC no longer PoCs (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:acf65e7b90c8313b3cf939d14b8299818d77cc18) (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a912eca8993334fe01e96f76168fa5e1889cb11a) Merged-In: Ie7195eb852b52aff2f58da8bd095d8684baceef6 Change-Id: Ie7195eb852b52aff2f58da8bd095d8684baceef6
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h1
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h1
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h3
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h1
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h11
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Output.cpp16
-rw-r--r--services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp7
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp4
8 files changed, 35 insertions, 9 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index 2203639b1a..bd0bcd77b7 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -152,6 +152,7 @@ public:
Region aboveOpaqueLayers;
// The region of the output which should be considered dirty
Region dirtyRegion;
+ int32_t aboveBlurRequests = 0;
};
virtual ~Output();
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index 428c19fe02..42fffe3c34 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -157,6 +157,7 @@ protected:
private:
void dirtyEntireOutput();
compositionengine::OutputLayer* findLayerRequestingBackgroundComposition() const;
+ void sanitizeOutputLayers() const;
void finishPrepareFrame();
ui::Dataspace getBestDataspace(ui::Dataspace*, bool*) const;
compositionengine::Output::ColorProfile pickColorProfile(
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index 2b383c1dfe..4a4880cd9b 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -94,6 +94,9 @@ struct OutputLayerCompositionState {
// order to save power.
Region outputSpaceBlockingRegionHint;
+ // ignore blur requests if there's just too many on top of this layer
+ bool ignoreBlur{false};
+
// Overrides the buffer, acquire fence, and display frame stored in LayerFECompositionState
struct {
std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
index 8e4e9af48c..1a7c0706a1 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
@@ -42,6 +42,7 @@ public:
const std::string& getName() const { return mState->getName(); }
int32_t getBackgroundBlurRadius() const { return mState->getBackgroundBlurRadius(); }
Rect getDisplayFrame() const { return mState->getDisplayFrame(); }
+ bool hasBlurBehind() const { return mState->hasBlurBehind(); }
const Region& getVisibleRegion() const { return mState->getVisibleRegion(); }
const sp<GraphicBuffer>& getBuffer() const {
return mState->getOutputLayer()->getLayerFE().getCompositionState()->buffer;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
index 5aec7c2e88..4b23ecdc5b 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
@@ -72,6 +72,7 @@ enum class LayerStateField : uint32_t {
SolidColor = 1u << 16,
BackgroundBlurRadius = 1u << 17,
BlurRegions = 1u << 18,
+ BlursDisabled = 1u << 19,
};
// clang-format on
@@ -232,7 +233,8 @@ public:
Rect getDisplayFrame() const { return mDisplayFrame.get(); }
const Region& getVisibleRegion() const { return mVisibleRegion.get(); }
bool hasBlurBehind() const {
- return mBackgroundBlurRadius.get() > 0 || !mBlurRegions.get().empty();
+ return (mBackgroundBlurRadius.get() > 0 || !mBlurRegions.get().empty()) &&
+ !mIsBlursDisabled.get();
}
int32_t getBackgroundBlurRadius() const { return mBackgroundBlurRadius.get(); }
aidl::android::hardware::graphics::composer3::Composition getCompositionType() const {
@@ -482,7 +484,10 @@ private:
return hash;
}};
- static const constexpr size_t kNumNonUniqueFields = 17;
+ OutputLayerState<bool, LayerStateField::BlursDisabled> mIsBlursDisabled{
+ [](auto layer) { return layer->getState().ignoreBlur; }};
+
+ static const constexpr size_t kNumNonUniqueFields = 18;
std::array<StateInterface*, kNumNonUniqueFields> getNonUniqueFields() {
std::array<const StateInterface*, kNumNonUniqueFields> constFields =
@@ -501,7 +506,7 @@ private:
&mAlpha, &mLayerMetadata, &mVisibleRegion, &mOutputDataspace,
&mPixelFormat, &mColorTransform, &mCompositionType, &mSidebandStream,
&mBuffer, &mSolidColor, &mBackgroundBlurRadius, &mBlurRegions,
- &mFrameNumber,
+ &mFrameNumber, &mIsBlursDisabled
};
}
};
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 1598fd135a..66ec2f75ce 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -706,6 +706,9 @@ void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE,
// one, or create a new one if we do not.
auto result = ensureOutputLayer(prevOutputLayerIndex, layerFE);
+ coverage.aboveBlurRequests += static_cast<int32_t>(layerFEState->backgroundBlurRadius > 0 ||
+ !layerFEState->blurRegions.empty());
+
// Store the layer coverage information into the layer state as some of it
// is useful later.
auto& outputLayerState = result->editState();
@@ -720,6 +723,11 @@ void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE,
? outputState.transform.transform(
transparentRegion.intersect(outputState.layerStackSpace.getContent()))
: Region();
+
+ // See b/399120953: blurs are so expensive that they may be susceptible to compression side
+ // channel attacks
+ static constexpr auto kMaxBlurRequests = 10;
+ outputLayerState.ignoreBlur = coverage.aboveBlurRequests > kMaxBlurRequests;
}
void Output::setReleasedLayers(const compositionengine::CompositionRefreshArgs&) {
@@ -1333,7 +1341,7 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests(
const Region viewportRegion(outputState.layerStackSpace.getContent());
bool firstLayer = true;
- bool disableBlurs = false;
+ bool disableBlursWholesale = false;
sp<GraphicBuffer> previousOverrideBuffer = nullptr;
for (auto* layer : getOutputLayersOrderedByZ()) {
@@ -1350,7 +1358,8 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests(
continue;
}
- disableBlurs |= layerFEState->sidebandStream != nullptr;
+ disableBlursWholesale |= layerFEState->sidebandStream != nullptr;
+ bool disableBlurForLayer = layer->getState().ignoreBlur || disableBlursWholesale;
const bool clientComposition = layer->requiresClientComposition();
@@ -1381,7 +1390,8 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests(
layer->getLayerFE().getDebugName());
}
} else {
- LayerFE::ClientCompositionTargetSettings::BlurSetting blurSetting = disableBlurs
+ LayerFE::ClientCompositionTargetSettings::BlurSetting blurSetting =
+ disableBlurForLayer
? LayerFE::ClientCompositionTargetSettings::BlurSetting::Disabled
: (layer->getState().overrideInfo.disableBackgroundBlur
? LayerFE::ClientCompositionTargetSettings::BlurSetting::
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index d6f02ee42a..10844a804d 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -193,9 +193,14 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te
std::vector<renderengine::LayerSettings> layerSettings;
renderengine::LayerSettings highlight;
for (const auto& layer : mLayers) {
+ auto blurSettings = targetSettings;
+ if (!layer.hasBlurBehind()) {
+ blurSettings.blurSetting =
+ LayerFE::ClientCompositionTargetSettings::BlurSetting::Disabled;
+ }
const auto clientCompositionList =
layer.getState()->getOutputLayer()->getLayerFE().prepareClientCompositionList(
- targetSettings);
+ blurSettings);
layerSettings.insert(layerSettings.end(), clientCompositionList.cbegin(),
clientCompositionList.cend());
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
index 0e9db369e8..2e4dc25f0a 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -990,12 +990,12 @@ TEST_F(CachedSetTest, addBlur) {
EXPECT_CALL(*layerFE1,
prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::
- Enabled)))
+ Disabled)))
.WillOnce(Return(clientCompList1));
EXPECT_CALL(*layerFE2,
prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::
- Enabled)))
+ Disabled)))
.WillOnce(Return(clientCompList2));
EXPECT_CALL(*layerFE3,
prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(