Loading services/surfaceflinger/SurfaceFlinger.cpp +24 −10 Original line number Original line Diff line number Diff line Loading @@ -287,6 +287,8 @@ const String16 sRotateSurfaceFlinger("android.permission.ROTATE_SURFACE_FLINGER" const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); const String16 sControlDisplayBrightness("android.permission.CONTROL_DISPLAY_BRIGHTNESS"); const String16 sControlDisplayBrightness("android.permission.CONTROL_DISPLAY_BRIGHTNESS"); const String16 sDump("android.permission.DUMP"); const String16 sDump("android.permission.DUMP"); const String16 sCaptureBlackoutContent("android.permission.CAPTURE_BLACKOUT_CONTENT"); const char* KERNEL_IDLE_TIMER_PROP = "graphics.display.kernel_idle_timer.enabled"; const char* KERNEL_IDLE_TIMER_PROP = "graphics.display.kernel_idle_timer.enabled"; // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading Loading @@ -5718,6 +5720,14 @@ static Dataspace pickDataspaceFromColorMode(const ColorMode colorMode) { } } } } static bool hasCaptureBlackoutContentPermission() { IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int uid = ipc->getCallingUid(); return uid == AID_GRAPHICS || uid == AID_SYSTEM || PermissionCache::checkPermission(sCaptureBlackoutContent, pid, uid); } static status_t validateScreenshotPermissions(const CaptureArgs& captureArgs) { static status_t validateScreenshotPermissions(const CaptureArgs& captureArgs) { IPCThreadState* ipc = IPCThreadState::self(); IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int pid = ipc->getCallingPid(); Loading Loading @@ -5888,6 +5898,10 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, Rect layerStackSpaceRect; Rect layerStackSpaceRect; ui::Dataspace dataspace; ui::Dataspace dataspace; bool captureSecureLayers; bool captureSecureLayers; // Call this before holding mStateLock to avoid any deadlocking. bool canCaptureBlackoutContent = hasCaptureBlackoutContentPermission(); { { Mutex::Autolock lock(mStateLock); Mutex::Autolock lock(mStateLock); Loading @@ -5897,9 +5911,8 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, return NAME_NOT_FOUND; return NAME_NOT_FOUND; } } const int uid = IPCThreadState::self()->getCallingUid(); if (!canCaptureBlackoutContent && const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM; parent->getCurrentState().flags & layer_state_t::eLayerSecure) { if (!forSystem && parent->getCurrentState().flags & layer_state_t::eLayerSecure) { ALOGW("Attempting to capture secure layer: PERMISSION_DENIED"); ALOGW("Attempting to capture secure layer: PERMISSION_DENIED"); return PERMISSION_DENIED; return PERMISSION_DENIED; } } Loading Loading @@ -6049,8 +6062,7 @@ status_t SurfaceFlinger::captureScreenCommon( return BAD_VALUE; return BAD_VALUE; } } const int uid = IPCThreadState::self()->getCallingUid(); bool canCaptureBlackoutContent = hasCaptureBlackoutContentPermission(); const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM; static_cast<void>(schedule([=, renderAreaFuture = std::move(renderAreaFuture)]() mutable { static_cast<void>(schedule([=, renderAreaFuture = std::move(renderAreaFuture)]() mutable { if (mRefreshPending) { if (mRefreshPending) { Loading @@ -6070,8 +6082,9 @@ status_t SurfaceFlinger::captureScreenCommon( status_t result = NO_ERROR; status_t result = NO_ERROR; renderArea->render([&] { renderArea->render([&] { result = renderScreenImplLocked(*renderArea, traverseLayers, buffer, forSystem, result = renderScreenImplLocked(*renderArea, traverseLayers, buffer, regionSampling, grayscale, captureResults); canCaptureBlackoutContent, regionSampling, grayscale, captureResults); }); }); captureResults.result = result; captureResults.result = result; Loading @@ -6083,8 +6096,9 @@ status_t SurfaceFlinger::captureScreenCommon( status_t SurfaceFlinger::renderScreenImplLocked( status_t SurfaceFlinger::renderScreenImplLocked( const RenderArea& renderArea, TraverseLayersFunction traverseLayers, const RenderArea& renderArea, TraverseLayersFunction traverseLayers, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool forSystem, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, bool grayscale, ScreenCaptureResults& captureResults) { bool canCaptureBlackoutContent, bool regionSampling, bool grayscale, ScreenCaptureResults& captureResults) { ATRACE_CALL(); ATRACE_CALL(); traverseLayers([&](Layer* layer) { traverseLayers([&](Layer* layer) { Loading @@ -6097,7 +6111,7 @@ status_t SurfaceFlinger::renderScreenImplLocked( // We allow the system server to take screenshots of secure layers for // We allow the system server to take screenshots of secure layers for // use in situations like the Screen-rotation animation and place // use in situations like the Screen-rotation animation and place // the impetus on WindowManager to not persist them. // the impetus on WindowManager to not persist them. if (captureResults.capturedSecureLayers && !forSystem) { if (captureResults.capturedSecureLayers && !canCaptureBlackoutContent) { ALOGW("FB is protected: PERMISSION_DENIED"); ALOGW("FB is protected: PERMISSION_DENIED"); return PERMISSION_DENIED; return PERMISSION_DENIED; } } Loading services/surfaceflinger/SurfaceFlinger.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -911,8 +911,8 @@ private: const sp<IScreenCaptureListener>&); const sp<IScreenCaptureListener>&); status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction, status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction, const std::shared_ptr<renderengine::ExternalTexture>&, const std::shared_ptr<renderengine::ExternalTexture>&, bool forSystem, bool regionSampling, bool grayscale, bool canCaptureBlackoutContent, bool regionSampling, ScreenCaptureResults&); bool grayscale, ScreenCaptureResults&); sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock); sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock); sp<DisplayDevice> getDisplayById(DisplayId displayId) const REQUIRES(mStateLock); sp<DisplayDevice> getDisplayById(DisplayId displayId) const REQUIRES(mStateLock); Loading services/surfaceflinger/tests/LayerTypeTransaction_test.cpp +6 −1 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #pragma clang diagnostic ignored "-Wconversion" #pragma clang diagnostic ignored "-Wconversion" #include <gui/BufferItemConsumer.h> #include <gui/BufferItemConsumer.h> #include <private/android_filesystem_config.h> #include "TransactionTestHarnesses.h" #include "TransactionTestHarnesses.h" namespace android { namespace android { Loading Loading @@ -170,7 +171,11 @@ TEST_P(LayerTypeTransactionTest, SetFlagsSecure) { args.displayToken = mDisplay; args.displayToken = mDisplay; ScreenCaptureResults captureResults; ScreenCaptureResults captureResults; { // Ensure the UID is not root because root has all permissions UIDFaker f(AID_APP_START); ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(args, captureResults)); ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(args, captureResults)); } Transaction().setFlags(layer, 0, layer_state_t::eLayerSecure).apply(true); Transaction().setFlags(layer, 0, layer_state_t::eLayerSecure).apply(true); ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, captureResults)); ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, captureResults)); Loading services/surfaceflinger/tests/ScreenCapture_test.cpp +12 −4 Original line number Original line Diff line number Diff line Loading @@ -84,7 +84,11 @@ TEST_F(ScreenCaptureTest, SetFlagsSecureEUidSystem) { Transaction().show(layer).setLayer(layer, INT32_MAX).apply(true); Transaction().show(layer).setLayer(layer, INT32_MAX).apply(true); { // Ensure the UID is not root because root has all permissions UIDFaker f(AID_APP_START); ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(mCaptureArgs, mCaptureResults)); ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(mCaptureArgs, mCaptureResults)); } UIDFaker f(AID_SYSTEM); UIDFaker f(AID_SYSTEM); Loading Loading @@ -528,7 +532,7 @@ TEST_F(ScreenCaptureTest, CaptureInvalidLayer) { ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults)); ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults)); } } TEST_F(ScreenCaptureTest, CaputureSecureLayer) { TEST_F(ScreenCaptureTest, CaptureSecureLayer) { sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, ISurfaceComposerClient::eFXSurfaceBufferState); ISurfaceComposerClient::eFXSurfaceBufferState); sp<SurfaceControl> secureLayer = sp<SurfaceControl> secureLayer = Loading @@ -552,8 +556,12 @@ TEST_F(ScreenCaptureTest, CaputureSecureLayer) { args.childrenOnly = false; args.childrenOnly = false; ScreenCaptureResults captureResults; ScreenCaptureResults captureResults; { // Ensure the UID is not root because root has all permissions UIDFaker f(AID_APP_START); // Call from outside system with secure layers will result in permission denied // Call from outside system with secure layers will result in permission denied ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(args, captureResults)); ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(args, captureResults)); } UIDFaker f(AID_SYSTEM); UIDFaker f(AID_SYSTEM); Loading Loading
services/surfaceflinger/SurfaceFlinger.cpp +24 −10 Original line number Original line Diff line number Diff line Loading @@ -287,6 +287,8 @@ const String16 sRotateSurfaceFlinger("android.permission.ROTATE_SURFACE_FLINGER" const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); const String16 sControlDisplayBrightness("android.permission.CONTROL_DISPLAY_BRIGHTNESS"); const String16 sControlDisplayBrightness("android.permission.CONTROL_DISPLAY_BRIGHTNESS"); const String16 sDump("android.permission.DUMP"); const String16 sDump("android.permission.DUMP"); const String16 sCaptureBlackoutContent("android.permission.CAPTURE_BLACKOUT_CONTENT"); const char* KERNEL_IDLE_TIMER_PROP = "graphics.display.kernel_idle_timer.enabled"; const char* KERNEL_IDLE_TIMER_PROP = "graphics.display.kernel_idle_timer.enabled"; // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading Loading @@ -5718,6 +5720,14 @@ static Dataspace pickDataspaceFromColorMode(const ColorMode colorMode) { } } } } static bool hasCaptureBlackoutContentPermission() { IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int uid = ipc->getCallingUid(); return uid == AID_GRAPHICS || uid == AID_SYSTEM || PermissionCache::checkPermission(sCaptureBlackoutContent, pid, uid); } static status_t validateScreenshotPermissions(const CaptureArgs& captureArgs) { static status_t validateScreenshotPermissions(const CaptureArgs& captureArgs) { IPCThreadState* ipc = IPCThreadState::self(); IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int pid = ipc->getCallingPid(); Loading Loading @@ -5888,6 +5898,10 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, Rect layerStackSpaceRect; Rect layerStackSpaceRect; ui::Dataspace dataspace; ui::Dataspace dataspace; bool captureSecureLayers; bool captureSecureLayers; // Call this before holding mStateLock to avoid any deadlocking. bool canCaptureBlackoutContent = hasCaptureBlackoutContentPermission(); { { Mutex::Autolock lock(mStateLock); Mutex::Autolock lock(mStateLock); Loading @@ -5897,9 +5911,8 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, return NAME_NOT_FOUND; return NAME_NOT_FOUND; } } const int uid = IPCThreadState::self()->getCallingUid(); if (!canCaptureBlackoutContent && const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM; parent->getCurrentState().flags & layer_state_t::eLayerSecure) { if (!forSystem && parent->getCurrentState().flags & layer_state_t::eLayerSecure) { ALOGW("Attempting to capture secure layer: PERMISSION_DENIED"); ALOGW("Attempting to capture secure layer: PERMISSION_DENIED"); return PERMISSION_DENIED; return PERMISSION_DENIED; } } Loading Loading @@ -6049,8 +6062,7 @@ status_t SurfaceFlinger::captureScreenCommon( return BAD_VALUE; return BAD_VALUE; } } const int uid = IPCThreadState::self()->getCallingUid(); bool canCaptureBlackoutContent = hasCaptureBlackoutContentPermission(); const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM; static_cast<void>(schedule([=, renderAreaFuture = std::move(renderAreaFuture)]() mutable { static_cast<void>(schedule([=, renderAreaFuture = std::move(renderAreaFuture)]() mutable { if (mRefreshPending) { if (mRefreshPending) { Loading @@ -6070,8 +6082,9 @@ status_t SurfaceFlinger::captureScreenCommon( status_t result = NO_ERROR; status_t result = NO_ERROR; renderArea->render([&] { renderArea->render([&] { result = renderScreenImplLocked(*renderArea, traverseLayers, buffer, forSystem, result = renderScreenImplLocked(*renderArea, traverseLayers, buffer, regionSampling, grayscale, captureResults); canCaptureBlackoutContent, regionSampling, grayscale, captureResults); }); }); captureResults.result = result; captureResults.result = result; Loading @@ -6083,8 +6096,9 @@ status_t SurfaceFlinger::captureScreenCommon( status_t SurfaceFlinger::renderScreenImplLocked( status_t SurfaceFlinger::renderScreenImplLocked( const RenderArea& renderArea, TraverseLayersFunction traverseLayers, const RenderArea& renderArea, TraverseLayersFunction traverseLayers, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool forSystem, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, bool grayscale, ScreenCaptureResults& captureResults) { bool canCaptureBlackoutContent, bool regionSampling, bool grayscale, ScreenCaptureResults& captureResults) { ATRACE_CALL(); ATRACE_CALL(); traverseLayers([&](Layer* layer) { traverseLayers([&](Layer* layer) { Loading @@ -6097,7 +6111,7 @@ status_t SurfaceFlinger::renderScreenImplLocked( // We allow the system server to take screenshots of secure layers for // We allow the system server to take screenshots of secure layers for // use in situations like the Screen-rotation animation and place // use in situations like the Screen-rotation animation and place // the impetus on WindowManager to not persist them. // the impetus on WindowManager to not persist them. if (captureResults.capturedSecureLayers && !forSystem) { if (captureResults.capturedSecureLayers && !canCaptureBlackoutContent) { ALOGW("FB is protected: PERMISSION_DENIED"); ALOGW("FB is protected: PERMISSION_DENIED"); return PERMISSION_DENIED; return PERMISSION_DENIED; } } Loading
services/surfaceflinger/SurfaceFlinger.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -911,8 +911,8 @@ private: const sp<IScreenCaptureListener>&); const sp<IScreenCaptureListener>&); status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction, status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction, const std::shared_ptr<renderengine::ExternalTexture>&, const std::shared_ptr<renderengine::ExternalTexture>&, bool forSystem, bool regionSampling, bool grayscale, bool canCaptureBlackoutContent, bool regionSampling, ScreenCaptureResults&); bool grayscale, ScreenCaptureResults&); sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock); sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock); sp<DisplayDevice> getDisplayById(DisplayId displayId) const REQUIRES(mStateLock); sp<DisplayDevice> getDisplayById(DisplayId displayId) const REQUIRES(mStateLock); Loading
services/surfaceflinger/tests/LayerTypeTransaction_test.cpp +6 −1 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #pragma clang diagnostic ignored "-Wconversion" #pragma clang diagnostic ignored "-Wconversion" #include <gui/BufferItemConsumer.h> #include <gui/BufferItemConsumer.h> #include <private/android_filesystem_config.h> #include "TransactionTestHarnesses.h" #include "TransactionTestHarnesses.h" namespace android { namespace android { Loading Loading @@ -170,7 +171,11 @@ TEST_P(LayerTypeTransactionTest, SetFlagsSecure) { args.displayToken = mDisplay; args.displayToken = mDisplay; ScreenCaptureResults captureResults; ScreenCaptureResults captureResults; { // Ensure the UID is not root because root has all permissions UIDFaker f(AID_APP_START); ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(args, captureResults)); ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(args, captureResults)); } Transaction().setFlags(layer, 0, layer_state_t::eLayerSecure).apply(true); Transaction().setFlags(layer, 0, layer_state_t::eLayerSecure).apply(true); ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, captureResults)); ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, captureResults)); Loading
services/surfaceflinger/tests/ScreenCapture_test.cpp +12 −4 Original line number Original line Diff line number Diff line Loading @@ -84,7 +84,11 @@ TEST_F(ScreenCaptureTest, SetFlagsSecureEUidSystem) { Transaction().show(layer).setLayer(layer, INT32_MAX).apply(true); Transaction().show(layer).setLayer(layer, INT32_MAX).apply(true); { // Ensure the UID is not root because root has all permissions UIDFaker f(AID_APP_START); ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(mCaptureArgs, mCaptureResults)); ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(mCaptureArgs, mCaptureResults)); } UIDFaker f(AID_SYSTEM); UIDFaker f(AID_SYSTEM); Loading Loading @@ -528,7 +532,7 @@ TEST_F(ScreenCaptureTest, CaptureInvalidLayer) { ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults)); ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults)); } } TEST_F(ScreenCaptureTest, CaputureSecureLayer) { TEST_F(ScreenCaptureTest, CaptureSecureLayer) { sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, ISurfaceComposerClient::eFXSurfaceBufferState); ISurfaceComposerClient::eFXSurfaceBufferState); sp<SurfaceControl> secureLayer = sp<SurfaceControl> secureLayer = Loading @@ -552,8 +556,12 @@ TEST_F(ScreenCaptureTest, CaputureSecureLayer) { args.childrenOnly = false; args.childrenOnly = false; ScreenCaptureResults captureResults; ScreenCaptureResults captureResults; { // Ensure the UID is not root because root has all permissions UIDFaker f(AID_APP_START); // Call from outside system with secure layers will result in permission denied // Call from outside system with secure layers will result in permission denied ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(args, captureResults)); ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(args, captureResults)); } UIDFaker f(AID_SYSTEM); UIDFaker f(AID_SYSTEM); Loading