Paranoid hwcomposer

when the hwcomposer gets a layers it needs to compose that is not sane
it considers it a fatal error instead of just returning -1.

(Taken from Change-Id: I026c5d977ec8efece71cf47ca28ad90a76c26b38
and Change-Id: I026c5d977ec8efece71cf47ca28ad90a76c26b38)

Bug: 72998203
Test: local
Change-Id: I5c7dcfe6e3249671890c7a55d728bdbb9d1b8970
diff --git a/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h b/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
index d4082f5..f810650 100644
--- a/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
+++ b/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
@@ -105,10 +105,44 @@
 
   static int validate(const native_handle* h) {
     const private_handle_t* hnd = (const private_handle_t*)h;
-    if (!h || h->version != sizeof(native_handle) ||
-        h->numInts != sNumInts() || h->numFds != sNumFds ||
-        hnd->magic != sMagic) {
-      ALOGE("invalid gralloc handle (at %p)", h);
+    if (!h) {
+      ALOGE("invalid gralloc handle (at %p): NULL pointer", h);
+      return -EINVAL;
+    }
+    if (h->version != sizeof(native_handle)) {
+      ALOGE(
+          "invalid gralloc handle (at %p): Wrong version(observed: %d, "
+          "expected: %zu)",
+          h,
+          h->version,
+          sizeof(native_handle));
+      return -EINVAL;
+    }
+    if (h->numInts != sNumInts()) {
+      ALOGE(
+          "invalid gralloc handle (at %p): Wrong number of ints(observed: %d, "
+          "expected: %d)",
+          h,
+          h->numInts,
+          sNumInts());
+      return -EINVAL;
+    }
+    if (h->numFds != sNumFds) {
+      ALOGE(
+          "invalid gralloc handle (at %p): Wrong number of file "
+          "descriptors(observed: %d, expected: %d)",
+          h,
+          h->numFds,
+          sNumFds);
+      return -EINVAL;
+    }
+    if (hnd->magic != sMagic) {
+      ALOGE(
+          "invalid gralloc handle (at %p): Wrong magic number(observed: %d, "
+          "expected: %d)",
+          h,
+          hnd->magic,
+          sMagic);
       return -EINVAL;
     }
     return 0;
diff --git a/guest/hals/hwcomposer/legacy/vsoc_composer.cpp b/guest/hals/hwcomposer/legacy/vsoc_composer.cpp
index ad86923..1eff72d 100644
--- a/guest/hals/hwcomposer/legacy/vsoc_composer.cpp
+++ b/guest/hals/hwcomposer/legacy/vsoc_composer.cpp
@@ -39,7 +39,7 @@
 namespace {
 
 // Ensures that the layer does not include any inconsistencies
-int SanityCheckLayer(const vsoc_hwc_layer& layer) {
+bool IsValidLayer(const vsoc_hwc_layer& layer) {
   // Check displayFrame
   if (layer.displayFrame.left > layer.displayFrame.right ||
       layer.displayFrame.top > layer.displayFrame.bottom) {
@@ -48,7 +48,7 @@
         "%d, bottom = %d]",
         __FUNCTION__, layer.displayFrame.left, layer.displayFrame.right,
         layer.displayFrame.top, layer.displayFrame.bottom);
-    return -EINVAL;
+    return false;
   }
   // Check sourceCrop
   if (layer.sourceCrop.left > layer.sourceCrop.right ||
@@ -58,14 +58,14 @@
         "%d, bottom = %d]",
         __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right,
         layer.sourceCrop.top, layer.sourceCrop.bottom);
-    return -EINVAL;
+    return false;
+  }
+  if (private_handle_t::validate(layer.handle) != 0) {
+    ALOGE("%s: Layer contains an invalid gralloc handle.", __FUNCTION__);
+    return false;
   }
   const private_handle_t* p_handle =
       reinterpret_cast<const private_handle_t*>(layer.handle);
-  if (!p_handle) {
-    ALOGE("Layer has a NULL buffer handle");
-    return -EINVAL;
-  }
   if (layer.sourceCrop.left < 0 || layer.sourceCrop.top < 0 ||
       layer.sourceCrop.right > p_handle->x_res ||
       layer.sourceCrop.bottom > p_handle->y_res) {
@@ -76,9 +76,47 @@
         __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right,
         layer.sourceCrop.top, layer.sourceCrop.bottom, p_handle->x_res,
         p_handle->y_res);
-    return -EINVAL;
+    return false;
   }
-  return 0;
+  return true;
+}
+
+bool IsValidComposition(int num_layers, vsoc_hwc_layer* layers) {
+  // The FRAMEBUFFER_TARGET layer needs to be sane only if there is at least one
+  // layer marked HWC_FRAMEBUFFER or if there is no layer marked HWC_OVERLAY
+  // (i.e some layers where composed with OpenGL, no layer marked overlay or
+  // framebuffer means that surfaceflinger decided to go for OpenGL without
+  // asking the hwcomposer first)
+  bool check_fb_target = true;
+  for (int idx = 0; idx < num_layers; ++idx) {
+    if (layers[idx].compositionType == HWC_FRAMEBUFFER) {
+      // There is at least one, so it needs to be checked.
+      // It may have been set to false before, so ensure it's set to true.
+      check_fb_target = true;
+      break;
+    }
+    if (layers[idx].compositionType == HWC_OVERLAY) {
+      // At least one overlay, we may not need to.
+      check_fb_target = false;
+    }
+  }
+
+  for (int idx = 0; idx < num_layers; ++idx) {
+    switch (layers[idx].compositionType) {
+    case HWC_FRAMEBUFFER_TARGET:
+      if (check_fb_target && !IsValidLayer(layers[idx])) {
+        return false;
+      }
+      break;
+    case HWC_OVERLAY:
+      if (!(layers[idx].flags & HWC_SKIP_LAYER) &&
+          !IsValidLayer(layers[idx])) {
+        return false;
+      }
+      break;
+    }
+  }
+  return true;
 }
 
 bool LayerNeedsScaling(const vsoc_hwc_layer& layer) {
@@ -598,6 +636,10 @@
 }
 
 int VSoCComposer::SetLayers(size_t num_layers, vsoc_hwc_layer* layers) {
+  if (!IsValidComposition(num_layers, layers)) {
+    LOG_FATAL("%s: Invalid composition requested", __FUNCTION__);
+    return -1;
+  }
   int targetFbs = 0;
   int buffer_idx = NextScreenBuffer();
 
@@ -617,14 +659,10 @@
     }
   }
 
-  // When the framebuffer target needs to be composed, it has to be go first.
+  // When the framebuffer target needs to be composed, it has to go first.
   if (fb_target) {
     for (size_t idx = 0; idx < num_layers; idx++) {
       if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) {
-        if (SanityCheckLayer(layers[idx]) != 0) {
-          ALOGE("FRAMEBUFFER_TARGET layer (%zu), failed sanity check", idx);
-          return -EINVAL;
-        }
         CompositeLayer(&layers[idx], buffer_idx);
         break;
       }
@@ -637,10 +675,6 @@
     }
     if (layers[idx].compositionType == HWC_OVERLAY &&
         !(layers[idx].flags & HWC_SKIP_LAYER)) {
-      if (SanityCheckLayer(layers[idx]) != 0) {
-          ALOGE("Layer (%zu) failed sanity check", idx);
-          return -EINVAL;
-      }
       CompositeLayer(&layers[idx], buffer_idx);
     }
   }