loader: Fix vkDestroySurfaceKHR call on NULL surf
authorMark Young <marky@lunarg.com>
Mon, 17 Oct 2016 18:27:36 +0000 (12:27 -0600)
committerMark Young <marky@lunarg.com>
Mon, 17 Oct 2016 18:27:36 +0000 (12:27 -0600)
Thanks to Derrick Owens @ AMD for catching this bug which can
cause a null-ptr dereference while running Khronos conformance
test dEQP-VK.wsi.win32.surface.destroy_null_handle.

Change-Id: I104a890cd23615458566ec71e072e21c76e989cb

loader/wsi.c

index 1cd5572..e4a282f 100644 (file)
@@ -165,29 +165,32 @@ terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
     struct loader_instance *ptr_instance = loader_get_instance(instance);
 
     VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
-    if (NULL != icd_surface->real_icd_surfaces) {
-        for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
-            if (ptr_instance->icd_libs.list[i].interface_version >=
-                ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
-                struct loader_icd *icd = &ptr_instance->icds[i];
-                if (NULL != icd->DestroySurfaceKHR &&
-                    NULL != (void *)icd_surface->real_icd_surfaces[i]) {
-                    icd->DestroySurfaceKHR(icd->instance,
-                                           icd_surface->real_icd_surfaces[i],
-                                           pAllocator);
-                    icd_surface->real_icd_surfaces[i] = (VkSurfaceKHR)NULL;
+    if (NULL != icd_surface) {
+        if (NULL != icd_surface->real_icd_surfaces) {
+            for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+                if (ptr_instance->icd_libs.list[i].interface_version >=
+                    ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+                    struct loader_icd *icd = &ptr_instance->icds[i];
+                    if (NULL != icd->DestroySurfaceKHR &&
+                        NULL != (void *)icd_surface->real_icd_surfaces[i]) {
+                        icd->DestroySurfaceKHR(
+                            icd->instance, icd_surface->real_icd_surfaces[i],
+                            pAllocator);
+                        icd_surface->real_icd_surfaces[i] = (VkSurfaceKHR)NULL;
+                    }
+                } else {
+                    // The real_icd_surface for any ICD not supporting the
+                    // proper interface version should be NULL.  If not, then
+                    // we have a problem.
+                    assert(NULL == (void *)icd_surface->real_icd_surfaces[i]);
                 }
-            } else {
-                // The real_icd_surface for any ICD not supporting the proper
-                // interface version should be NULL.  If not, then we have a
-                // problem.
-                assert(NULL == (void*)icd_surface->real_icd_surfaces[i]);
             }
+            loader_instance_heap_free(ptr_instance,
+                                      icd_surface->real_icd_surfaces);
         }
-        loader_instance_heap_free(ptr_instance, icd_surface->real_icd_surfaces);
-    }
 
-    loader_instance_heap_free(ptr_instance, (void *)surface);
+        loader_instance_heap_free(ptr_instance, (void *)surface);
+    }
 }
 
 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceSupportKHR