Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de619fa2 authored by Garfield Tan's avatar Garfield Tan
Browse files

Make a layer secure if its parent is secure.

Dialogs and context menus can be captured in screenshots even if their
parent layer/window is marked secure. Therefore we should let the secure
flag be inherited from their parents as well.

Bug: 169851503
Test: Screen capture can't capture dialogs in a window marked secure.
Test: atest libsurfaceflinger_unittest
Test: atest SurfaceFlinger_test:ScreenCaptureTest
Change-Id: I0f32a03aeb733682df787105b051c691d1da7bc6
parent 693291a8
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -778,7 +778,12 @@ bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {

bool Layer::isSecure() const {
    const State& s(mDrawingState);
    return (s.flags & layer_state_t::eLayerSecure);
    if (s.flags & layer_state_t::eLayerSecure) {
        return true;
    }

    const auto p = mDrawingParent.promote();
    return (p != nullptr) ? p->isSecure() : false;
}

// ----------------------------------------------------------------------------
+36 −1
Original line number Diff line number Diff line
@@ -109,6 +109,41 @@ TEST_F(ScreenCaptureTest, SetFlagsSecureEUidSystem) {
    sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
}

TEST_F(ScreenCaptureTest, CaptureChildSetParentFlagsSecureEUidSystem) {
    sp<SurfaceControl> parentLayer;
    ASSERT_NO_FATAL_FAILURE(
            parentLayer = createLayer("parent-test", 32, 32,
                                      ISurfaceComposerClient::eSecure |
                                              ISurfaceComposerClient::eFXSurfaceBufferQueue));
    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(parentLayer, Color::RED, 32, 32));

    sp<SurfaceControl> childLayer;
    ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("child-test", 10, 10,
                                                     ISurfaceComposerClient::eFXSurfaceBufferQueue,
                                                     parentLayer.get()));
    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(childLayer, Color::BLUE, 10, 10));

    Transaction().show(parentLayer).setLayer(parentLayer, INT32_MAX).show(childLayer).apply(true);

    UIDFaker f(AID_SYSTEM);

    {
        SCOPED_TRACE("as system");
        auto shot = screenshot();
        shot->expectColor(Rect(0, 0, 10, 10), Color::BLACK);
    }

    // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able
    // to receive them...we are expected to take care with the results.
    DisplayCaptureArgs args;
    args.displayToken = mDisplay;
    args.captureSecureLayers = true;
    ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, mCaptureResults));
    ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
    ScreenCapture sc(mCaptureResults.buffer);
    sc.expectColor(Rect(0, 0, 10, 10), Color::BLUE);
}

TEST_F(ScreenCaptureTest, CaptureSingleLayer) {
    LayerCaptureArgs captureArgs;
    captureArgs.layerHandle = mBGSurfaceControl->getHandle();
+94 −6
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <utils/String8.h>

#include "BufferQueueLayer.h"
#include "ContainerLayer.h"
#include "DisplayRenderArea.h"
#include "EffectLayer.h"
#include "Layer.h"
@@ -188,6 +189,7 @@ public:
    sp<compositionengine::mock::DisplaySurface> mDisplaySurface =
            new compositionengine::mock::DisplaySurface();
    mock::NativeWindow* mNativeWindow = new mock::NativeWindow();
    std::vector<sp<Layer>> mAuxiliaryLayers;

    sp<GraphicBuffer> mBuffer = new GraphicBuffer();
    ANativeWindowBuffer* mNativeWindowBuffer = mBuffer->getNativeBuffer();
@@ -762,10 +764,9 @@ struct SidebandLayerProperties : public BaseLayerProperties<SidebandLayerPropert
    static void setupREBufferCompositionCommonCallExpectations(CompositionTest* /*test*/) {}
};

struct SecureLayerProperties : public BaseLayerProperties<SecureLayerProperties> {
    using Base = BaseLayerProperties<SecureLayerProperties>;

    static constexpr uint32_t LAYER_FLAGS = ISurfaceComposerClient::eSecure;
template <typename LayerProperties>
struct CommonSecureLayerProperties : public BaseLayerProperties<LayerProperties> {
    using Base = BaseLayerProperties<LayerProperties>;

    static void setupInsecureREBufferCompositionCommonCallExpectations(CompositionTest* test) {
        EXPECT_CALL(*test->mRenderEngine, drawLayers)
@@ -806,6 +807,13 @@ struct SecureLayerProperties : public BaseLayerProperties<SecureLayerProperties>
    }
};

struct ParentSecureLayerProperties
      : public CommonSecureLayerProperties<ParentSecureLayerProperties> {};

struct SecureLayerProperties : public CommonSecureLayerProperties<SecureLayerProperties> {
    static constexpr uint32_t LAYER_FLAGS = ISurfaceComposerClient::eSecure;
};

struct CursorLayerProperties : public BaseLayerProperties<CursorLayerProperties> {
    using Base = BaseLayerProperties<CursorLayerProperties>;

@@ -841,6 +849,13 @@ struct BaseLayerVariant {
        Mock::VerifyAndClear(test->mRenderEngine);
        Mock::VerifyAndClearExpectations(test->mMessageQueue);

        initLayerDrawingStateAndComputeBounds(test, layer);

        return layer;
    }

    template <typename L>
    static void initLayerDrawingStateAndComputeBounds(CompositionTest* test, sp<L> layer) {
        auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
        layerDrawingState.layerStack = DEFAULT_LAYER_STACK;
        layerDrawingState.active.w = 100;
@@ -848,8 +863,6 @@ struct BaseLayerVariant {
        layerDrawingState.color = half4(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
                                        LayerProperties::COLOR[2], LayerProperties::COLOR[3]);
        layer->computeBounds(FloatRect(0, 0, 100, 100), ui::Transform(), 0.f /* shadowRadius */);

        return layer;
    }

    static void injectLayer(CompositionTest* test, sp<Layer> layer) {
@@ -970,6 +983,49 @@ struct BufferLayerVariant : public BaseLayerVariant<LayerProperties> {
    }
};

template <typename LayerProperties>
struct ContainerLayerVariant : public BaseLayerVariant<LayerProperties> {
    using Base = BaseLayerVariant<LayerProperties>;
    using FlingerLayerType = sp<ContainerLayer>;

    static FlingerLayerType createLayer(CompositionTest* test) {
        LayerCreationArgs args(test->mFlinger.flinger(), sp<Client>(), "test-container-layer",
                               LayerProperties::WIDTH, LayerProperties::HEIGHT,
                               LayerProperties::LAYER_FLAGS, LayerMetadata());
        FlingerLayerType layer = new ContainerLayer(args);
        Base::template initLayerDrawingStateAndComputeBounds(test, layer);
        return layer;
    }
};

template <typename LayerVariant, typename ParentLayerVariant>
struct ChildLayerVariant : public LayerVariant {
    using Base = LayerVariant;
    using FlingerLayerType = typename LayerVariant::FlingerLayerType;
    using ParentBase = ParentLayerVariant;

    static FlingerLayerType createLayer(CompositionTest* test) {
        // Need to create child layer first. Otherwise layer history size will be 2.
        FlingerLayerType layer = Base::createLayer(test);

        typename ParentBase::FlingerLayerType parentLayer = ParentBase::createLayer(test);
        parentLayer->addChild(layer);
        test->mFlinger.setLayerDrawingParent(layer, parentLayer);

        test->mAuxiliaryLayers.push_back(parentLayer);

        return layer;
    }

    static void cleanupInjectedLayers(CompositionTest* test) {
        // Clear auxiliary layers first so that child layer can be successfully destroyed in the
        // following call.
        test->mAuxiliaryLayers.clear();

        Base::cleanupInjectedLayers(test);
    }
};

/* ------------------------------------------------------------------------
 * Variants to control how the composition type is changed
 */
@@ -1358,6 +1414,38 @@ TEST_F(CompositionTest, captureScreenSecureBufferLayerOnInsecureDisplay) {
                            NoCompositionTypeVariant, REScreenshotResultVariant>>();
}

/* ------------------------------------------------------------------------
 *  Layers with a parent layer with ISurfaceComposerClient::eSecure, on a non-secure display
 */

TEST_F(CompositionTest,
       HWCComposedBufferLayerWithSecureParentLayerOnInsecureDisplayWithDirtyGeometry) {
    displayRefreshCompositionDirtyGeometry<
            CompositionCase<InsecureDisplaySetupVariant,
                            ChildLayerVariant<BufferLayerVariant<ParentSecureLayerProperties>,
                                              ContainerLayerVariant<SecureLayerProperties>>,
                            KeepCompositionTypeVariant<IComposerClient::Composition::CLIENT>,
                            ForcedClientCompositionResultVariant>>();
}

TEST_F(CompositionTest,
       HWCComposedBufferLayerWithSecureParentLayerOnInsecureDisplayWithDirtyFrame) {
    displayRefreshCompositionDirtyFrame<
            CompositionCase<InsecureDisplaySetupVariant,
                            ChildLayerVariant<BufferLayerVariant<ParentSecureLayerProperties>,
                                              ContainerLayerVariant<SecureLayerProperties>>,
                            KeepCompositionTypeVariant<IComposerClient::Composition::CLIENT>,
                            ForcedClientCompositionResultVariant>>();
}

TEST_F(CompositionTest, captureScreenBufferLayerWithSecureParentLayerOnInsecureDisplay) {
    captureScreenComposition<
            CompositionCase<InsecureDisplaySetupVariant,
                            ChildLayerVariant<BufferLayerVariant<ParentSecureLayerProperties>,
                                              ContainerLayerVariant<SecureLayerProperties>>,
                            NoCompositionTypeVariant, REScreenshotResultVariant>>();
}

/* ------------------------------------------------------------------------
 *  Cursor layers
 */
+4 −0
Original line number Diff line number Diff line
@@ -277,6 +277,10 @@ public:
        layer->mPotentialCursor = potentialCursor;
    }

    static void setLayerDrawingParent(const sp<Layer>& layer, const sp<Layer>& drawingParent) {
        layer->mDrawingParent = drawingParent;
    }

    /* ------------------------------------------------------------------------
     * Forwarding for functions being tested
     */