OSDN Git Service

[RESTRICT AUTOMERGE] Careful with screenshots containing secure layers!
authorRobert Carr <racarr@google.com>
Tue, 2 Apr 2019 21:18:56 +0000 (14:18 -0700)
committerNikoli Cartagena <dargeren@google.com>
Tue, 11 Jun 2019 01:52:34 +0000 (18:52 -0700)
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. Make sure
we use the new API from SurfaceFlinger to set FLAG_SECURE if our screenshot contains secure
content.

Bug: 69703445
Test: Transaction_test#SetFlagsSecureEUidSystem
Change-Id: I0dd36462867da52e6b1451f65f56c2c5d37538f3
(cherry picked from commit bab740f10e0812ba47d19931fdfe2fa7e02bbd0c)

core/jni/android_view_SurfaceControl.cpp
graphics/java/android/graphics/GraphicBuffer.java
services/core/java/com/android/server/wm/ScreenRotationAnimation.java

index 1529a6b..614a8ff 100644 (file)
@@ -171,9 +171,10 @@ static jobject nativeScreenshotToBuffer(JNIEnv* env, jclass clazz,
         maxLayer = INT32_MAX;
     }
     sp<GraphicBuffer> buffer;
+    bool capturedSecureLayers = false;
     status_t res = ScreenshotClient::capture(displayToken,
             sourceCrop, width, height, minLayer, maxLayer, useIdentityTransform,
-            rotation, captureSecureLayers, &buffer);
+            rotation, captureSecureLayers, &buffer, capturedSecureLayers);
     if (res != NO_ERROR) {
         return NULL;
     }
@@ -184,7 +185,8 @@ static jobject nativeScreenshotToBuffer(JNIEnv* env, jclass clazz,
             buffer->getHeight(),
             buffer->getPixelFormat(),
             (jint)buffer->getUsage(),
-            (jlong)buffer.get());
+            (jlong)buffer.get(),
+            capturedSecureLayers);
 }
 
 static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
@@ -1082,7 +1084,7 @@ int register_android_view_SurfaceControl(JNIEnv* env)
     jclass graphicsBufferClazz = FindClassOrDie(env, "android/graphics/GraphicBuffer");
     gGraphicBufferClassInfo.clazz = MakeGlobalRefOrDie(env, graphicsBufferClazz);
     gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz,
-            "createFromExisting", "(IIIIJ)Landroid/graphics/GraphicBuffer;");
+            "createFromExisting", "(IIIIJZ)Landroid/graphics/GraphicBuffer;");
 
     return err;
 }
index 53d2177..61dd37f 100644 (file)
@@ -52,6 +52,7 @@ public class GraphicBuffer implements Parcelable {
     private final int mHeight;
     private final int mFormat;
     private final int mUsage;
+    private final boolean mCapturedSecureLayers;
     // Note: do not rename, this field is used by native code
     private final long mNativeObject;
 
@@ -82,14 +83,23 @@ public class GraphicBuffer implements Parcelable {
     }
 
     /**
-     * Private use only. See {@link #create(int, int, int, int)}.
+     * Private use only. See {@link #create(int, int, int, int, boolean)}.
      */
-    private GraphicBuffer(int width, int height, int format, int usage, long nativeObject) {
+    private GraphicBuffer(int width, int height, int format, int usage, long nativeObject,
+                          boolean capturedSecureLayers) {
         mWidth = width;
         mHeight = height;
         mFormat = format;
         mUsage = usage;
         mNativeObject = nativeObject;
+        mCapturedSecureLayers = capturedSecureLayers;
+    }
+
+    /**
+     * Private use only. See {@link #create(int, int, int, int)}.
+     */
+    private GraphicBuffer(int width, int height, int format, int usage, long nativeObject) {
+        this(width, height, format, usage, nativeObject, false);
     }
 
     /**
@@ -97,15 +107,34 @@ public class GraphicBuffer implements Parcelable {
      * @hide
      */
     public static GraphicBuffer createFromExisting(int width, int height,
-            int format, int usage, long unwrappedNativeObject) {
+            int format, int usage, long unwrappedNativeObject,
+            boolean capturedSecureLayers) {
         long nativeObject = nWrapGraphicBuffer(unwrappedNativeObject);
         if (nativeObject != 0) {
-            return new GraphicBuffer(width, height, format, usage, nativeObject);
+            return new GraphicBuffer(width, height, format, usage, nativeObject,
+                                     capturedSecureLayers);
         }
         return null;
     }
 
     /**
+     * For SurfaceControl JNI. Provides and ignored value for capturedSecureLayers for backwards
+     * compatibility
+     * @hide
+     */
+    public static GraphicBuffer createFromExisting(int width, int height,
+            int format, int usage, long unwrappedNativeObject) {
+        return createFromExisting(width, height, format, usage, unwrappedNativeObject, false);
+    }
+
+    /**
+      * Returns true if the buffer contains visible secure layers.
+      */
+    public boolean doesContainSecureLayers() {
+        return mCapturedSecureLayers;
+    }
+
+    /**
      * Returns the width of this buffer in pixels.
      */
     public int getWidth() {
index e330703..1ff8ab5 100644 (file)
@@ -288,6 +288,12 @@ class ScreenRotationAnimation {
                     } catch (RuntimeException e) {
                         Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage());
                     }
+                    // If the screenshot contains secure layers, we have to make sure the
+                    // screenshot surface we display it in also has FLAG_SECURE so that
+                    // the user can not screenshot secure layers via the screenshot surface.
+                    if (gb.doesContainSecureLayers()) {
+                        t.setSecure(mSurfaceControl, true);
+                    }
                     t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT);
                     t.setAlpha(mSurfaceControl, 0);
                     t.show(mSurfaceControl);