aboutsummaryrefslogtreecommitdiff
path: root/layers
diff options
context:
space:
mode:
authorGabríel Arthúr Pétursson <gabriel@system.is>2018-03-21 22:44:11 +0000
committerDave Houlton <daveh@lunarg.com>2018-04-04 16:16:14 -0600
commit90605a51d8197d87f9b280d99c9da5e1627f0977 (patch)
tree0e27ddc22fc25c5eee3231ffd0139a6f5cedf738 /layers
parente86bb48e0aa57fb85865447c8d573cc724d71920 (diff)
downloadusermoji-90605a51d8197d87f9b280d99c9da5e1627f0977.tar.xz
layers: Avoid reading pointer to array when count is zero
Take for example VkSubmitInfo. It has, amongst others, two fields: waitSemaphoreCount and pWaitSemaphores. The specification states that if waitSemaphoreCount is zero, the application may leave pWaitSemaphores uninitialized (in essence, that field is ignored). The layers read that value anyway, triggering uninitialized read errors by memory sanitization tools. Fixes uninitialized read in QueueSubmitSemaphoresAndLayoutTracking.
Diffstat (limited to 'layers')
-rw-r--r--layers/parameter_validation.h22
-rw-r--r--layers/parameter_validation_utils.cpp16
2 files changed, 19 insertions, 19 deletions
diff --git a/layers/parameter_validation.h b/layers/parameter_validation.h
index 675d2245..15ebcbf4 100644
--- a/layers/parameter_validation.h
+++ b/layers/parameter_validation.h
@@ -227,9 +227,9 @@ static bool validate_required_pointer(debug_report_data *report_data, const char
* @param arrayRequired The 'array' parameter may not be NULL when true.
* @return Boolean value indicating that the call should be skipped.
*/
-template <typename T>
+template <typename T1, typename T2>
bool validate_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
- const ParameterName &arrayName, T count, const void *array, bool countRequired, bool arrayRequired,
+ const ParameterName &arrayName, T1 count, const T2 *array, bool countRequired, bool arrayRequired,
UNIQUE_VALIDATION_ERROR_CODE count_required_vuid, UNIQUE_VALIDATION_ERROR_CODE array_required_vuid) {
bool skip_call = false;
@@ -241,7 +241,7 @@ bool validate_array(debug_report_data *report_data, const char *apiName, const P
}
// Array parameters not tagged as optional cannot be NULL, unless the count is 0
- if ((array == NULL) && arrayRequired && (count != 0)) {
+ if (arrayRequired && (count != 0) && (*array == NULL)) {
skip_call |=
log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, array_required_vuid,
"%s: required parameter %s specified as NULL.", apiName, arrayName.get_name().c_str());
@@ -270,9 +270,9 @@ bool validate_array(debug_report_data *report_data, const char *apiName, const P
* @param arrayRequired The 'array' parameter may not be NULL when true.
* @return Boolean value indicating that the call should be skipped.
*/
-template <typename T>
+template <typename T1, typename T2>
bool validate_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
- const ParameterName &arrayName, const T *count, const void *array, bool countPtrRequired,
+ const ParameterName &arrayName, const T1 *count, const T2 *array, bool countPtrRequired,
bool countValueRequired, bool arrayRequired, UNIQUE_VALIDATION_ERROR_CODE count_required_vuid,
UNIQUE_VALIDATION_ERROR_CODE array_required_vuid) {
bool skip_call = false;
@@ -284,7 +284,7 @@ bool validate_array(debug_report_data *report_data, const char *apiName, const P
"%s: required parameter %s specified as NULL", apiName, countName.get_name().c_str());
}
} else {
- skip_call |= validate_array(report_data, apiName, countName, arrayName, array ? (*count) : 0, array, countValueRequired,
+ skip_call |= validate_array(report_data, apiName, countName, arrayName, *array ? (*count) : 0, &array, countValueRequired,
arrayRequired, count_required_vuid, array_required_vuid);
}
@@ -353,7 +353,7 @@ bool validate_struct_type_array(debug_report_data *report_data, const char *apiN
bool skip_call = false;
if ((count == 0) || (array == NULL)) {
- skip_call |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired,
+ skip_call |= validate_array(report_data, apiName, countName, arrayName, count, &array, countRequired, arrayRequired,
VALIDATION_ERROR_UNDEFINED, vuid);
} else {
// Verify that all structs in the array have the correct type
@@ -464,7 +464,7 @@ bool validate_handle_array(debug_report_data *report_data, const char *api_name,
bool skip_call = false;
if ((count == 0) || (array == NULL)) {
- skip_call |= validate_array(report_data, api_name, count_name, array_name, count, array, count_required, array_required,
+ skip_call |= validate_array(report_data, api_name, count_name, array_name, count, &array, count_required, array_required,
VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
} else {
// Verify that no handles in the array are VK_NULL_HANDLE
@@ -505,7 +505,7 @@ static bool validate_string_array(debug_report_data *report_data, const char *ap
bool skip_call = false;
if ((count == 0) || (array == NULL)) {
- skip_call |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired,
+ skip_call |= validate_array(report_data, apiName, countName, arrayName, count, &array, countRequired, arrayRequired,
count_required_vuid, array_required_vuid);
} else {
// Verify that strings in the array are not NULL
@@ -700,7 +700,7 @@ static bool validate_ranged_enum_array(debug_report_data *report_data, const cha
bool skip_call = false;
if ((count == 0) || (array == NULL)) {
- skip_call |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired,
+ skip_call |= validate_array(report_data, apiName, countName, arrayName, count, &array, countRequired, arrayRequired,
VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
} else {
for (uint32_t i = 0; i < count; ++i) {
@@ -805,7 +805,7 @@ static bool validate_flags_array(debug_report_data *report_data, const char *api
bool skip_call = false;
if ((count == 0) || (array == NULL)) {
- skip_call |= validate_array(report_data, api_name, count_name, array_name, count, array, count_required, array_required,
+ skip_call |= validate_array(report_data, api_name, count_name, array_name, count, &array, count_required, array_required,
VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
} else {
// Verify that all VkFlags values in the array
diff --git a/layers/parameter_validation_utils.cpp b/layers/parameter_validation_utils.cpp
index b9adf037..ba071d8d 100644
--- a/layers/parameter_validation_utils.cpp
+++ b/layers/parameter_validation_utils.cpp
@@ -1599,7 +1599,7 @@ bool pv_vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache
report_data, "vkCreateGraphicsPipelines",
ParameterName("pCreateInfos[%i].pMultisampleState->rasterizationSamples", ParameterName::IndexVector{i}),
ParameterName("pCreateInfos[%i].pMultisampleState->pSampleMask", ParameterName::IndexVector{i}),
- pCreateInfos[i].pMultisampleState->rasterizationSamples, pCreateInfos[i].pMultisampleState->pSampleMask,
+ pCreateInfos[i].pMultisampleState->rasterizationSamples, &pCreateInfos[i].pMultisampleState->pSampleMask,
true, false, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
skip |= validate_bool32(
@@ -1765,7 +1765,7 @@ bool pv_vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache
report_data, "vkCreateGraphicsPipelines",
ParameterName("pCreateInfos[%i].pColorBlendState->attachmentCount", ParameterName::IndexVector{i}),
ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments", ParameterName::IndexVector{i}),
- pCreateInfos[i].pColorBlendState->attachmentCount, pCreateInfos[i].pColorBlendState->pAttachments, false,
+ pCreateInfos[i].pColorBlendState->attachmentCount, &pCreateInfos[i].pColorBlendState->pAttachments, false,
true, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
if (pCreateInfos[i].pColorBlendState->pAttachments != NULL) {
@@ -2054,7 +2054,7 @@ bool pv_vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, u
// This is an array of handles, where the elements are allowed to be VK_NULL_HANDLE, and does not require any validation beyond
// validate_array()
skip |= validate_array(report_data, "vkFreeDescriptorSets", "descriptorSetCount", "pDescriptorSets", descriptorSetCount,
- pDescriptorSets, true, true, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
+ &pDescriptorSets, true, true, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
return skip;
}
@@ -2238,7 +2238,7 @@ bool pv_vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_
// This is an array of handles, where the elements are allowed to be VK_NULL_HANDLE, and does not require any validation beyond
// validate_array()
skip |= validate_array(report_data, "vkFreeCommandBuffers", "commandBufferCount", "pCommandBuffers", commandBufferCount,
- pCommandBuffers, true, true, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
+ &pCommandBuffers, true, true, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
return skip;
}
@@ -2639,7 +2639,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDe
instance_layer_data *local_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
bool skip =
validate_array(local_data->report_data, "vkEnumerateDeviceExtensionProperties", "pPropertyCount", "pProperties",
- pPropertyCount, pProperties, true, false, false, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_2761f401);
+ pPropertyCount, &pProperties, true, false, false, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_2761f401);
if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
return local_data->dispatch_table.EnumerateDeviceExtensionProperties(physicalDevice, NULL, pPropertyCount, pProperties);
@@ -2742,12 +2742,12 @@ bool pv_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
skip |= validate_struct_pnext(device_data->report_data, "QueuePresentKHR", "pCreateInfo->pNext->pNext", NULL,
present_regions->pNext, 0, NULL, GeneratedHeaderVersion, VALIDATION_ERROR_1121c40d);
skip |= validate_array(device_data->report_data, "QueuePresentKHR", "pCreateInfo->pNext->swapchainCount",
- "pCreateInfo->pNext->pRegions", present_regions->swapchainCount, present_regions->pRegions, true,
- false, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
+ "pCreateInfo->pNext->pRegions", present_regions->swapchainCount, &present_regions->pRegions,
+ true, false, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
for (uint32_t i = 0; i < present_regions->swapchainCount; ++i) {
skip |= validate_array(device_data->report_data, "QueuePresentKHR", "pCreateInfo->pNext->pRegions[].rectangleCount",
"pCreateInfo->pNext->pRegions[].pRectangles", present_regions->pRegions[i].rectangleCount,
- present_regions->pRegions[i].pRectangles, true, false, VALIDATION_ERROR_UNDEFINED,
+ &present_regions->pRegions[i].pRectangles, true, false, VALIDATION_ERROR_UNDEFINED,
VALIDATION_ERROR_UNDEFINED);
}
}