layers: Fix possible crash in draw_state layer
authorMark Lobodzinski <mark@lunarg.com>
Fri, 12 Feb 2016 21:10:53 +0000 (14:10 -0700)
committerJon Ashburn <jon@lunarg.com>
Thu, 18 Feb 2016 22:42:04 +0000 (15:42 -0700)
Uninitialized descriptor slots are not filled this could cause
null pointer dereferences.

layers/draw_state.cpp

index 1e7df0d..23bb7bd 100644 (file)
@@ -1697,17 +1697,43 @@ static VkBool32 validate_dynamic_offsets(layer_data* my_data, const GLOBAL_CB_NO
     uint32_t dynOffsetIndex = 0;
     VkDeviceSize bufferSize = 0;
     for (auto set_node : activeSetNodes) {
-        for (uint32_t i=0; i < set_node->descriptorCount; ++i) {
-            switch (set_node->ppDescriptors[i]->sType) {
+        for (uint32_t i = 0; i < set_node->descriptorCount; ++i) {
+            if (set_node->ppDescriptors[i] != NULL) {
+                switch (set_node->ppDescriptors[i]->sType) {
                 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
-                    pWDS = (VkWriteDescriptorSet*)set_node->ppDescriptors[i];
-                    if ((pWDS->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
-                        (pWDS->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
-                        for (uint32_t j=0; j<pWDS->descriptorCount; ++j) {
-                            bufferSize = my_data->bufferMap[pWDS->pBufferInfo[j].buffer].create_info->size;
+                    pWDS = (VkWriteDescriptorSet *)set_node->ppDescriptors[i];
+                    if ((pWDS->descriptorType ==
+                         VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
+                        (pWDS->descriptorType ==
+                         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
+                        for (uint32_t j = 0; j < pWDS->descriptorCount; ++j) {
+                            bufferSize =
+                                my_data->bufferMap[pWDS->pBufferInfo[j].buffer]
+                                    .create_info->size;
                             if (pWDS->pBufferInfo[j].range == VK_WHOLE_SIZE) {
-                              if ((pCB->dynamicOffsets[dynOffsetIndex] +
-                                   pWDS->pBufferInfo[j].offset) > bufferSize) {
+                                if ((pCB->dynamicOffsets[dynOffsetIndex] +
+                                     pWDS->pBufferInfo[j].offset) > bufferSize) {
+                                    result |= log_msg(
+                                        my_data->report_data,
+                                        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                        VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
+                                        (uint64_t)set_node->set, __LINE__,
+                                        DRAWSTATE_DYNAMIC_OFFSET_OVERFLOW, "DS",
+                                        "VkDescriptorSet (%#" PRIxLEAST64
+                                        ") bound as set #%u has range of "
+                                        "VK_WHOLE_SIZE but dynamic offset %u "
+                                        "combined with offet %#" PRIxLEAST64
+                                        " oversteps its buffer (%#" PRIxLEAST64
+                                        ") which has a size of %#" PRIxLEAST64 ".",
+                                        (uint64_t)set_node->set, i,
+                                        pCB->dynamicOffsets[dynOffsetIndex],
+                                        pWDS->pBufferInfo[j].offset,
+                                        (uint64_t)pWDS->pBufferInfo[j].buffer,
+                                        bufferSize);
+                                }
+                            } else if ((pCB->dynamicOffsets[dynOffsetIndex] +
+                                        pWDS->pBufferInfo[j].offset +
+                                        pWDS->pBufferInfo[j].range) > bufferSize) {
                                 result |= log_msg(
                                     my_data->report_data,
                                     VK_DEBUG_REPORT_ERROR_BIT_EXT,
@@ -1715,17 +1741,18 @@ static VkBool32 validate_dynamic_offsets(layer_data* my_data, const GLOBAL_CB_NO
                                     (uint64_t)set_node->set, __LINE__,
                                     DRAWSTATE_DYNAMIC_OFFSET_OVERFLOW, "DS",
                                     "VkDescriptorSet (%#" PRIxLEAST64
-                                    ") bound as set #%u has range of "
-                                    "VK_WHOLE_SIZE but dynamic offset %u "
-                                    "combined with offet %#" PRIxLEAST64
-                                    " oversteps its buffer (%#" PRIxLEAST64
+                                    ") bound as set #%u has dynamic offset %u. "
+                                    "Combined with offet %#" PRIxLEAST64
+                                    " and range %#" PRIxLEAST64
+                                    " from its update, this oversteps its buffer "
+                                    "(%#" PRIxLEAST64
                                     ") which has a size of %#" PRIxLEAST64 ".",
                                     (uint64_t)set_node->set, i,
                                     pCB->dynamicOffsets[dynOffsetIndex],
                                     pWDS->pBufferInfo[j].offset,
+                                    pWDS->pBufferInfo[j].range,
                                     (uint64_t)pWDS->pBufferInfo[j].buffer,
                                     bufferSize);
-                              }
                             } else if ((pCB->dynamicOffsets[dynOffsetIndex] +
                                         pWDS->pBufferInfo[j].offset +
                                         pWDS->pBufferInfo[j].range) >
@@ -1758,6 +1785,7 @@ static VkBool32 validate_dynamic_offsets(layer_data* my_data, const GLOBAL_CB_NO
                 default: // Currently only shadowing Write update nodes so shouldn't get here
                     assert(0);
                     continue;
+                }
             }
         }
     }