OSDN Git Service

surfaceflinger: protect Client::mParentLayer with a lock
authorChia-I Wu <olv@google.com>
Thu, 15 Jun 2017 21:01:18 +0000 (14:01 -0700)
committerChia-I Wu <olv@google.com>
Fri, 16 Jun 2017 17:54:50 +0000 (10:54 -0700)
Updates to wp<> is not atomic.  Use Client::mLock to protect
mParentLayer.

Bug: 38505866
Test: camera and youtube work
Change-Id: I2739382d5bb99961a47c1011963b6f676d34eec6

services/surfaceflinger/Client.cpp
services/surfaceflinger/Client.h

index e9a2513..8ba6cb9 100644 (file)
@@ -57,9 +57,19 @@ Client::~Client()
 }
 
 void Client::setParentLayer(const sp<Layer>& parentLayer) {
+    Mutex::Autolock _l(mLock);
     mParentLayer = parentLayer;
 }
 
+sp<Layer> Client::getParentLayer(bool* outParentDied) const {
+    Mutex::Autolock _l(mLock);
+    sp<Layer> parent = mParentLayer.promote();
+    if (outParentDied != nullptr) {
+        *outParentDied = (mParentLayer != nullptr && parent == nullptr);
+    }
+    return parent;
+}
+
 status_t Client::initCheck() const {
     return NO_ERROR;
 }
@@ -108,7 +118,7 @@ status_t Client::onTransact(
      // We grant an exception in the case that the Client has a "parent layer", as its
      // effects will be scoped to that layer.
      if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0)
-             && (mParentLayer.promote() == nullptr)) {
+             && (getParentLayer() == nullptr)) {
          // we're called from a different process, do the real check
          if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
          {
@@ -135,11 +145,12 @@ status_t Client::createSurface(
             return NAME_NOT_FOUND;
         }
     }
-    if (parent == nullptr && mParentLayer != nullptr) {
-        parent = mParentLayer.promote();
+    if (parent == nullptr) {
+        bool parentDied;
+        parent = getParentLayer(&parentDied);
         // If we had a parent, but it died, we've lost all
         // our capabilities.
-        if (parent == nullptr) {
+        if (parentDied) {
             return NAME_NOT_FOUND;
         }
     }
index b5f98b8..2aab28f 100644 (file)
@@ -71,12 +71,13 @@ private:
     virtual status_t onTransact(
         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
 
+    sp<Layer> getParentLayer(bool* outParentDied = nullptr) const;
+
     // constant
     sp<SurfaceFlinger> mFlinger;
 
     // protected by mLock
     DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;
-
     wp<Layer> mParentLayer;
 
     // thread-safe