summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Carr <racarr@google.com>2019-04-02 16:32:58 -0700
committerhamzeh <hamzeh@google.com>2019-05-10 16:44:47 -0700
commit9b3bc2e474c33c7722eaa4b3f3aa79e4b58374d5 (patch)
tree8037d1bfeaaa92f567f9dd54714aca7bea8aab65
parentb0b22e049618ce3b018d6a44522fb8a9a71498c4 (diff)
downloadnative-9b3bc2e474c33c7722eaa4b3f3aa79e4b58374d5.tar.gz
[RESTRICT AUTOMERGE] SurfaceFlinger: Indicate whether we have captured secure layers.
For purposes of the screen rotation animation the system server is allowed to capture secure (not protected) layers and trusted not to persist screenshots which may contain secure layers. However when displaying the screen rotation animation, the layer the screenshot is placed on will itself not be secure, so if we record the animation the recording will contain persisted versions of the secure content. Here we forward whether the screenshot contains secure content so that system server can do the right thing. Bug: b/69703445 Test: Transaction_test#SetFlagsSecureEUidSystem Change-Id: If493a39257b5e15410360a3df23f3e0fc8cf295c (cherry picked from commit a1586de21f6c9191b99d2f3c815fcd15c48114e1)
-rw-r--r--libs/gui/ISurfaceComposer.cpp10
-rw-r--r--libs/gui/SurfaceComposerClient.cpp10
-rw-r--r--libs/gui/include/gui/ISurfaceComposer.h15
-rw-r--r--libs/gui/include/gui/SurfaceComposerClient.h3
-rw-r--r--libs/gui/tests/Surface_test.cpp8
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp28
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h5
-rw-r--r--services/surfaceflinger/tests/Transaction_test.cpp4
8 files changed, 56 insertions, 27 deletions
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index fa81a926a0..81c7f9c57c 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -103,6 +103,7 @@ public:
}
virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
+ bool& outCapturedSecureLayers,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
ISurfaceComposer::Rotation rotation, bool captureSecureLayers) {
@@ -130,6 +131,8 @@ public:
*outBuffer = new GraphicBuffer();
reply.read(**outBuffer);
+ outCapturedSecureLayers = reply.readBool();
+
return err;
}
@@ -618,12 +621,15 @@ status_t BnSurfaceComposer::onTransact(
int32_t rotation = data.readInt32();
bool captureSecureLayers = static_cast<bool>(data.readInt32());
- status_t res = captureScreen(display, &outBuffer, sourceCrop, reqWidth, reqHeight,
- minLayerZ, maxLayerZ, useIdentityTransform,
+ bool capturedSecureLayers = false;
+ status_t res = captureScreen(display, &outBuffer, capturedSecureLayers, sourceCrop, reqWidth,
+ reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
static_cast<ISurfaceComposer::Rotation>(rotation), captureSecureLayers);
+
reply->writeInt32(res);
if (res == NO_ERROR) {
reply->write(*outBuffer);
+ reply->writeBool(capturedSecureLayers);
}
return NO_ERROR;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index aab3ebe7ab..6fd7f2d23f 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -764,11 +764,12 @@ status_t SurfaceComposerClient::getHdrCapabilities(const sp<IBinder>& display,
status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
bool useIdentityTransform, uint32_t rotation,
- bool captureSecureLayers, sp<GraphicBuffer>* outBuffer) {
+ bool captureSecureLayers, sp<GraphicBuffer>* outBuffer,
+ bool& outCapturedSecureLayers) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == NULL) return NO_INIT;
- status_t ret = s->captureScreen(display, outBuffer, sourceCrop, reqWidth, reqHeight, minLayerZ,
- maxLayerZ, useIdentityTransform,
+ status_t ret = s->captureScreen(display, outBuffer, outCapturedSecureLayers, sourceCrop,
+ reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
static_cast<ISurfaceComposer::Rotation>(rotation),
captureSecureLayers);
if (ret != NO_ERROR) {
@@ -781,8 +782,9 @@ status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop,
uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
bool useIdentityTransform, uint32_t rotation,
sp<GraphicBuffer>* outBuffer) {
+ bool ignored;
return capture(display, sourceCrop, reqWidth, reqHeight,
- minLayerZ, maxLayerZ, useIdentityTransform, rotation, false, outBuffer);
+ minLayerZ, maxLayerZ, useIdentityTransform, rotation, false, outBuffer, ignored);
}
status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index fbd72c8d9d..a672ce4ed8 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -175,11 +175,22 @@ public:
* This function will fail if there is a secure window on screen.
*/
virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
- Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
- int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
+ bool& outCapturedSecureLayers, Rect sourceCrop,
+ uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ,
+ int32_t maxLayerZ, bool useIdentityTransform,
Rotation rotation = eRotateNone,
bool captureSecureLayers = false) = 0;
+ virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
+ Rect sourceCrop,
+ uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ,
+ int32_t maxLayerZ, bool useIdentityTransform,
+ Rotation rotation = eRotateNone,
+ bool captureSecureLayers = false) {
+ bool ignored;
+ return captureScreen(display, outBuffer, ignored, sourceCrop, reqWidth, reqHeight, minLayerZ,
+ maxLayerZ, useIdentityTransform, rotation, captureSecureLayers);
+ }
/**
* Capture a subtree of the layer hierarchy, potentially ignoring the root node.
*/
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index b66c40f2fd..9ce1a73ace 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -312,7 +312,8 @@ public:
static status_t capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
bool useIdentityTransform, uint32_t rotation,
- bool captureSecureLayers, sp<GraphicBuffer>* outBuffer);
+ bool captureSecureLayers, sp<GraphicBuffer>* outBuffer,
+ bool& outCapturedSecureLayers);
static status_t capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
bool useIdentityTransform, uint32_t rotation,
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 7417567642..4effd653b8 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -126,7 +126,7 @@ TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenPurgatorized) {
}
// This test probably doesn't belong here.
-TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
+TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersDontSucceed) {
sp<ANativeWindow> anw(mSurface);
// Verify the screenshot works with no protected buffers.
@@ -134,7 +134,8 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
sp<IBinder> display(sf->getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain));
sp<GraphicBuffer> outBuffer;
- ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
+ bool ignored;
+ ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, ignored, Rect(),
64, 64, 0, 0x7fffffff, false));
ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(),
@@ -165,7 +166,7 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
&buf));
ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
}
- ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
+ ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, ignored, Rect(),
64, 64, 0, 0x7fffffff, false));
}
@@ -598,6 +599,7 @@ public:
ColorMode /*colorMode*/) override { return NO_ERROR; }
status_t captureScreen(const sp<IBinder>& /*display*/,
sp<GraphicBuffer>* /*outBuffer*/,
+ bool& /* outCapturedSecureLayers */,
Rect /*sourceCrop*/, uint32_t /*reqWidth*/, uint32_t /*reqHeight*/,
int32_t /*minLayerZ*/, int32_t /*maxLayerZ*/,
bool /*useIdentityTransform*/,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 49f0df8fdd..9d0531ef6b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4705,7 +4705,8 @@ private:
const int mApi;
};
-status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
+status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
+ sp<GraphicBuffer>* outBuffer, bool& outCapturedSecureLayers,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
int32_t minLayerZ, int32_t maxLayerZ,
bool useIdentityTransform,
@@ -4733,7 +4734,8 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, sp<GraphicBuf
auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
device, minLayerZ, maxLayerZ, std::placeholders::_1);
- return captureScreenCommon(renderArea, traverseLayers, outBuffer, useIdentityTransform);
+ return captureScreenCommon(renderArea, traverseLayers, outBuffer, useIdentityTransform,
+ outCapturedSecureLayers);
}
status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
@@ -4847,13 +4849,16 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
visitor(layer);
});
};
- return captureScreenCommon(renderArea, traverseLayers, outBuffer, false);
+ bool outCapturedSecureLayers = false;
+ return captureScreenCommon(renderArea, traverseLayers, outBuffer, false,
+ outCapturedSecureLayers);
}
status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
TraverseLayersFunction traverseLayers,
sp<GraphicBuffer>* outBuffer,
- bool useIdentityTransform) {
+ bool useIdentityTransform,
+ bool& outCapturedSecureLayers) {
ATRACE_CALL();
renderArea.updateDimensions(mPrimaryDisplayOrientation);
@@ -4891,7 +4896,8 @@ status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
Mutex::Autolock _l(mStateLock);
renderArea.render([&]() {
result = captureScreenImplLocked(renderArea, traverseLayers, (*outBuffer).get(),
- useIdentityTransform, forSystem, &fd);
+ useIdentityTransform, forSystem, &fd,
+ outCapturedSecureLayers);
});
}
@@ -5042,21 +5048,19 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
status_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea,
TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer,
- bool useIdentityTransform,
- bool forSystem,
- int* outSyncFd) {
+ bool useIdentityTransform, bool forSystem,
+ int* outSyncFd, bool& outCapturedSecureLayers) {
ATRACE_CALL();
- bool secureLayerIsVisible = false;
-
traverseLayers([&](Layer* layer) {
- secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() && layer->isSecure());
+ outCapturedSecureLayers =
+ outCapturedSecureLayers || (layer->isVisible() && layer->isSecure());
});
// We allow the system server to take screenshots of secure layers for
// use in situations like the Screen-rotation animation and place
// the impetus on WindowManager to not persist them.
- if (secureLayerIsVisible && !forSystem) {
+ if (outCapturedSecureLayers && !forSystem) {
ALOGW("FB is protected: PERMISSION_DENIED");
return PERMISSION_DENIED;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 29f54144ea..b123defa6f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -418,6 +418,7 @@ private:
virtual sp<IDisplayEventConnection> createDisplayEventConnection(
ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp);
virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
+ bool& outCapturedSecureLayers,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
ISurfaceComposer::Rotation rotation, bool captureSecureLayers);
@@ -568,11 +569,11 @@ private:
bool yswap, bool useIdentityTransform);
status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
sp<GraphicBuffer>* outBuffer,
- bool useIdentityTransform);
+ bool useIdentityTransform, bool& outCapturedSecureLayers);
status_t captureScreenImplLocked(const RenderArea& renderArea,
TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer, bool useIdentityTransform,
- bool forSystem, int* outSyncFd);
+ bool forSystem, int* outSyncFd, bool& outCapturedSecureLayers);
void traverseLayersInDisplay(const sp<const DisplayDevice>& display, int32_t minLayerZ,
int32_t maxLayerZ, const LayerVector::Visitor& visitor);
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index deca17799c..6ce2075a3d 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -941,9 +941,11 @@ TEST_F(LayerTransactionTest, SetFlagsSecureEUidSystem) {
// 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.
+ bool outCapturedSecureLayers = false;
ASSERT_EQ(NO_ERROR,
- composer->captureScreen(mDisplay, &outBuffer,
+ composer->captureScreen(mDisplay, &outBuffer, outCapturedSecureLayers,
Rect(), 0, 0, 0, INT_MAX, false, ISurfaceComposer::eRotateNone, true));
+ ASSERT_EQ(true, outCapturedSecureLayers);
ScreenCapture sc(outBuffer);
sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
}