SurfaceFlinger: Safely cast from IBinder to Layer::Handle

Bug: b/193034677, b/193034683, b/193033243
Test: go/wm-smoke, presubmit

Change-Id: Iece64fca254edfd0b82e05ad9629824b2364cc13
Merged-In: Iece64fca254edfd0b82e05ad9629824b2364cc13
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index e4a777f..6ee13ce 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -819,11 +819,7 @@
 }
 
 bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) {
-    sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
-    if (handle == nullptr) {
-        return false;
-    }
-    sp<Layer> relative = handle->owner.promote();
+    sp<Layer> relative = fromHandle(relativeToHandle).promote();
     if (relative == nullptr) {
         return false;
     }
@@ -1609,8 +1605,7 @@
 bool Layer::reparent(const sp<IBinder>& newParentHandle) {
     sp<Layer> newParent;
     if (newParentHandle != nullptr) {
-        auto handle = static_cast<Handle*>(newParentHandle.get());
-        newParent = handle->owner.promote();
+        newParent = fromHandle(newParentHandle).promote();
         if (newParent == nullptr) {
             ALOGE("Unable to promote Layer handle");
             return false;
@@ -1985,24 +1980,10 @@
     mDrawingParent = mCurrentParent;
 }
 
-static wp<Layer> extractLayerFromBinder(const wp<IBinder>& weakBinderHandle) {
-    if (weakBinderHandle == nullptr) {
-        return nullptr;
-    }
-    sp<IBinder> binderHandle = weakBinderHandle.promote();
-    if (binderHandle == nullptr) {
-        return nullptr;
-    }
-    sp<Layer::Handle> handle = static_cast<Layer::Handle*>(binderHandle.get());
-    if (handle == nullptr) {
-        return nullptr;
-    }
-    return handle->owner;
-}
 
 void Layer::setInputInfo(const InputWindowInfo& info) {
     mDrawingState.inputInfo = info;
-    mDrawingState.touchableRegionCrop = extractLayerFromBinder(info.touchableRegionCropHandle);
+    mDrawingState.touchableRegionCrop = fromHandle(info.touchableRegionCropHandle.promote());
     mDrawingState.modified = true;
     mFlinger->mInputInfoChanged = true;
     setTransactionFlags(eTransactionNeeded);
@@ -2561,6 +2542,23 @@
     mFlinger->mNumClones++;
 }
 
+const String16 Layer::Handle::kDescriptor = String16("android.Layer.Handle");
+
+wp<Layer> Layer::fromHandle(const sp<IBinder>& handleBinder) {
+    if (handleBinder == nullptr) {
+        return nullptr;
+    }
+
+    BBinder* b = handleBinder->localBinder();
+    if (b == nullptr || b->getInterfaceDescriptor() != Handle::kDescriptor) {
+        return nullptr;
+    }
+
+    // We can safely cast this binder since its local and we verified its interface descriptor.
+    sp<Handle> handle = static_cast<Handle*>(handleBinder.get());
+    return handle->owner;
+}
+
 // ---------------------------------------------------------------------------
 
 std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) {