diff options
| -rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 6 | ||||
| -rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 15 | ||||
| -rw-r--r-- | libs/gui/include/gui/ISurfaceComposer.h | 3 | ||||
| -rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 4 | ||||
| -rw-r--r-- | libs/gui/tests/Surface_test.cpp | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 8 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/Transaction_test.cpp | 53 |
9 files changed, 87 insertions, 13 deletions
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index f77eeb246c..d549346276 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -100,7 +100,7 @@ public: const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, - ISurfaceComposer::Rotation rotation) { + ISurfaceComposer::Rotation rotation, bool captureSecureLayers) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); @@ -111,6 +111,7 @@ public: data.writeUint32(reqHeight); data.writeInt32(static_cast<int32_t>(useIdentityTransform)); data.writeInt32(static_cast<int32_t>(rotation)); + data.writeInt32(static_cast<int32_t>(captureSecureLayers)); status_t result = remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); if (result != NO_ERROR) { ALOGE("captureScreen failed to transact: %d", result); @@ -884,10 +885,11 @@ status_t BnSurfaceComposer::onTransact( uint32_t reqHeight = data.readUint32(); bool useIdentityTransform = static_cast<bool>(data.readInt32()); int32_t rotation = data.readInt32(); + bool captureSecureLayers = static_cast<bool>(data.readInt32()); status_t res = captureScreen(display, &outBuffer, reqDataspace, reqPixelFormat, sourceCrop, reqWidth, reqHeight, useIdentityTransform, - static_cast<ISurfaceComposer::Rotation>(rotation)); + static_cast<ISurfaceComposer::Rotation>(rotation), captureSecureLayers); reply->writeInt32(res); if (res == NO_ERROR) { reply->write(*outBuffer); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 8c2538ca19..7770518cf6 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1469,18 +1469,27 @@ status_t SurfaceComposerClient::isWideColorDisplay(const sp<IBinder>& display, status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace, const ui::PixelFormat reqPixelFormat, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, - uint32_t rotation, sp<GraphicBuffer>* outBuffer) { + uint32_t rotation, bool captureSecureLayers, sp<GraphicBuffer>* outBuffer) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == nullptr) return NO_INIT; status_t ret = s->captureScreen(display, outBuffer, reqDataSpace, reqPixelFormat, sourceCrop, - reqWidth, reqHeight, useIdentityTransform, - static_cast<ISurfaceComposer::Rotation>(rotation)); + reqWidth, reqHeight, useIdentityTransform, + static_cast<ISurfaceComposer::Rotation>(rotation), + captureSecureLayers); if (ret != NO_ERROR) { return ret; } return ret; } +status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace, + const ui::PixelFormat reqPixelFormat, Rect sourceCrop, + uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, + uint32_t rotation, sp<GraphicBuffer>* outBuffer) { + return capture(display, reqDataSpace, reqPixelFormat, sourceCrop, reqWidth, + reqHeight, useIdentityTransform, rotation, false, outBuffer); +} + status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace, const ui::PixelFormat reqPixelFormat, Rect sourceCrop, diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index e6700e77dd..8654f5ef0a 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -209,7 +209,8 @@ public: const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, - Rotation rotation = eRotateNone) = 0; + Rotation rotation = eRotateNone, + bool captureSecureLayers = false) = 0; /** * Capture the specified screen. This requires READ_FRAME_BUFFER * permission. This function will fail if there is a secure window on diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index cb38209f65..6d21bff1f7 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -454,6 +454,10 @@ public: static status_t capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace, const ui::PixelFormat reqPixelFormat, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, + uint32_t rotation, bool captureSecureLayers, sp<GraphicBuffer>* outBuffer); + static status_t capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace, + const ui::PixelFormat reqPixelFormat, Rect sourceCrop, + uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, uint32_t rotation, sp<GraphicBuffer>* outBuffer); static status_t captureLayers(const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace, const ui::PixelFormat reqPixelFormat, Rect sourceCrop, diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index f1278537e4..e14c698088 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -615,7 +615,8 @@ public: const ui::Dataspace /*reqDataspace*/, const ui::PixelFormat /*reqPixelFormat*/, Rect /*sourceCrop*/, uint32_t /*reqWidth*/, uint32_t /*reqHeight*/, - bool /*useIdentityTransform*/, Rotation /*rotation*/) override { + bool /*useIdentityTransform*/, Rotation /*rotation*/, + bool /*captureSecureLayers*/) override { return NO_ERROR; } virtual status_t captureLayers(const sp<IBinder>& /*parentHandle*/, diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index a827c47ba9..c80925ee78 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -255,17 +255,18 @@ public: device->getCompositionDataSpace(), rotation) {} DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, ui::Dataspace reqDataSpace, - ui::Transform::orientation_flags rotation) + ui::Transform::orientation_flags rotation, bool allowSecureLayers = true) : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, reqDataSpace, getDisplayRotation(rotation, device->getInstallOrientation())), mDevice(device), - mSourceCrop(sourceCrop) {} + mSourceCrop(sourceCrop), + mAllowSecureLayers(allowSecureLayers) {} const ui::Transform& getTransform() const override { return mDevice->getTransform(); } Rect getBounds() const override { return mDevice->getBounds(); } int getHeight() const override { return mDevice->getHeight(); } int getWidth() const override { return mDevice->getWidth(); } - bool isSecure() const override { return mDevice->isSecure(); } + bool isSecure() const override { return mAllowSecureLayers && mDevice->isSecure(); } const sp<const DisplayDevice> getDisplayDevice() const override { return mDevice; } bool needsFiltering() const override { @@ -356,6 +357,7 @@ private: const sp<const DisplayDevice> mDevice; const Rect mSourceCrop; + const bool mAllowSecureLayers; }; }; // namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index df558e5e82..ad50f93295 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -5300,7 +5300,8 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken, const ui::PixelFormat reqPixelFormat, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, - ISurfaceComposer::Rotation rotation) { + ISurfaceComposer::Rotation rotation, + bool captureSecureLayers) { ATRACE_CALL(); if (!displayToken) return BAD_VALUE; @@ -5323,7 +5324,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken, } DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, reqDataspace, - renderAreaRotation); + renderAreaRotation, captureSecureLayers); auto traverseLayers = std::bind(&SurfaceFlinger::traverseLayersInDisplay, this, display, std::placeholders::_1); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 31b4fb6232..29b3ab2133 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -442,7 +442,8 @@ private: status_t captureScreen(const sp<IBinder>& displayToken, sp<GraphicBuffer>* outBuffer, const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, - bool useIdentityTransform, ISurfaceComposer::Rotation rotation) override; + bool useIdentityTransform, ISurfaceComposer::Rotation rotation, + bool captureSecureLayers) override; status_t captureLayers(const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer, const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop, float frameScale, bool childrenOnly) override; diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 181dac6136..34cdff778a 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -33,6 +33,7 @@ #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> #include <private/gui/ComposerService.h> +#include <private/android_filesystem_config.h> #include <ui/ColorSpace.h> #include <ui/DisplayInfo.h> @@ -41,6 +42,8 @@ #include <math.h> #include <math/vec3.h> +#include <sys/types.h> +#include <unistd.h> #include "BufferGenerator.h" @@ -1201,6 +1204,56 @@ TEST_P(LayerTypeTransactionTest, SetFlagsSecure) { composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false)); } +/** RAII Wrapper around get/seteuid */ +class UIDFaker { + uid_t oldId; +public: + UIDFaker(uid_t uid) { + oldId = geteuid(); + seteuid(uid); + } + ~UIDFaker() { + seteuid(oldId); + } +}; + +TEST_F(LayerTransactionTest, SetFlagsSecureEUidSystem) { + sp<SurfaceControl> layer; + ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); + + sp<ISurfaceComposer> composer = ComposerService::getComposerService(); + sp<GraphicBuffer> outBuffer; + Transaction() + .setFlags(layer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure) + .apply(true); + ASSERT_EQ(PERMISSION_DENIED, + composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false)); + + UIDFaker f(AID_SYSTEM); + + // By default the system can capture screenshots with secure layers but they + // will be blacked out + ASSERT_EQ(NO_ERROR, + composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false)); + + { + SCOPED_TRACE("as system"); + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), 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. + ASSERT_EQ(NO_ERROR, + composer->captureScreen(mDisplay, &outBuffer, + ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, + Rect(), 0, 0, false, + ISurfaceComposer::eRotateNone, true)); + ScreenCapture sc(outBuffer); + sc.expectColor(Rect(0, 0, 32, 32), Color::RED); +} + TEST_P(LayerRenderTypeTransactionTest, SetTransparentRegionHintBasic_BufferQueue) { const Rect top(0, 0, 32, 16); const Rect bottom(0, 16, 32, 32); |