Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vulkan] Fix heap buffer overflow in Vulkan extension handling discovered by ASAN #7740

Merged
merged 1 commit into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/runtime/internal/string_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class StringTable {
void clear(void *user_context);

// fills the contents of the table (copies strings from given array)
void fill(void *user_context, const char **array, size_t coun);
void fill(void *user_context, const char **array, size_t count);

// assign the entry at given index the given string
void assign(void *user_context, size_t index, const char *str, size_t length = 0); // if length is zero, strlen is used
Expand Down Expand Up @@ -88,9 +88,10 @@ StringTable::~StringTable() {

void StringTable::resize(void *user_context, size_t capacity) {
pointers.resize(user_context, capacity);
while (contents.size() < capacity) {
contents.resize(user_context, capacity);
for (size_t n = 0; n < contents.size(); ++n) {
StringStorage *storage_ptr = StringStorage::create(user_context, contents.current_allocator());
contents.append(user_context, storage_ptr);
contents.assign(user_context, n, storage_ptr);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/runtime/vulkan_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,13 +312,13 @@ int vk_create_device(void *user_context, const StringTable &requested_layers, Vk
}

debug(user_context) << " found " << (uint32_t)required_device_extensions.size() << " required extensions for device!\n";
for (int n = 0; n < (int)required_device_extensions.size(); ++n) {
for (uint32_t n = 0; n < required_device_extensions.size(); ++n) {
debug(user_context) << " required extension: " << required_device_extensions[n] << "\n";
}

// enable all available optional extensions
debug(user_context) << " checking for " << (uint32_t)optional_device_extensions.size() << " optional extensions for device ...\n";
for (int n = 0; n < (int)optional_device_extensions.size(); ++n) {
for (uint32_t n = 0; n < optional_device_extensions.size(); ++n) {
if (supported_device_extensions.contains(optional_device_extensions[n])) {
debug(user_context) << " optional extension: " << optional_device_extensions[n] << "\n";
required_device_extensions.append(user_context, optional_device_extensions[n]);
Expand Down
23 changes: 11 additions & 12 deletions src/runtime/vulkan_extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,10 @@ uint32_t vk_get_supported_instance_extensions(void *user_context, StringTable &e
return 0;
}

debug(user_context) << "Vulkan: Checking vkEnumerateInstanceExtensionProperties for extensions ...\n";

uint32_t avail_ext_count = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &avail_ext_count, nullptr);
debug(user_context) << "Vulkan: vkEnumerateInstanceExtensionProperties found " << avail_ext_count << " extensions ...\n";

if (avail_ext_count) {
BlockStorage::Config config;
Expand All @@ -170,7 +171,7 @@ uint32_t vk_get_supported_instance_extensions(void *user_context, StringTable &e

for (uint32_t n = 0; n < avail_ext_count; ++n) {
const VkExtensionProperties *properties = static_cast<const VkExtensionProperties *>(extension_properties[n]);
debug(user_context) << " extension: " << properties->extensionName << "\n";
debug(user_context) << " [" << n << "]: " << properties->extensionName << "\n";
}

ext_table.resize(user_context, avail_ext_count);
Expand All @@ -179,7 +180,7 @@ uint32_t vk_get_supported_instance_extensions(void *user_context, StringTable &e
ext_table.assign(user_context, n, properties->extensionName);
}
}

debug(user_context) << "Vulkan: vkEnumerateInstanceExtensionProperties found " << avail_ext_count << " extensions ...\n";
return avail_ext_count;
}

Expand All @@ -197,11 +198,7 @@ uint32_t vk_get_optional_device_extensions(void *user_context, StringTable &ext_
"VK_KHR_shader_float16_int8",
"VK_KHR_shader_float_controls"};
const uint32_t optional_ext_count = sizeof(optional_ext_table) / sizeof(optional_ext_table[0]);

ext_table.resize(user_context, optional_ext_count);
for (uint32_t n = 0; n < optional_ext_count; ++n) {
ext_table.assign(user_context, n, optional_ext_table[n]);
}
ext_table.fill(user_context, (const char **)optional_ext_table, optional_ext_count);
return optional_ext_count;
}

Expand All @@ -212,10 +209,10 @@ uint32_t vk_get_supported_device_extensions(void *user_context, VkPhysicalDevice
return 0;
}

debug(user_context) << "Vulkan: Checking vkEnumerateDeviceExtensionProperties for extensions ...\n";

uint32_t avail_ext_count = 0;
vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &avail_ext_count, nullptr);
debug(user_context) << "Vulkan: vkEnumerateDeviceExtensionProperties found " << avail_ext_count << " extensions ...\n";

if (avail_ext_count > 0) {
BlockStorage::Config config;
config.entry_size = sizeof(VkExtensionProperties);
Expand All @@ -229,7 +226,7 @@ uint32_t vk_get_supported_device_extensions(void *user_context, VkPhysicalDevice

for (uint32_t n = 0; n < avail_ext_count; ++n) {
const VkExtensionProperties *properties = static_cast<const VkExtensionProperties *>(extension_properties[n]);
debug(user_context) << " extension: " << properties->extensionName << "\n";
debug(user_context) << " [" << n << "]: " << properties->extensionName << "\n";
}

ext_table.resize(user_context, avail_ext_count);
Expand All @@ -239,17 +236,19 @@ uint32_t vk_get_supported_device_extensions(void *user_context, VkPhysicalDevice
}
}

debug(user_context) << "Vulkan: vkEnumerateDeviceExtensionProperties found " << avail_ext_count << " extensions ...\n";
return avail_ext_count;
}

bool vk_validate_required_extension_support(void *user_context,
const StringTable &required_extensions,
const StringTable &supported_extensions) {
debug(user_context) << "Vulkan: Validating " << uint32_t(required_extensions.size()) << " extensions ...\n";
bool validated = true;
for (uint32_t n = 0; n < required_extensions.size(); ++n) {
const char *extension = required_extensions[n];
if (!supported_extensions.contains(extension)) {
debug(user_context) << "Vulkan: Missing required extension: '" << extension << "'! \n";
debug(user_context) << "Vulkan: Missing required extension: '" << extension << "'!\n";
validated = false;
}
}
Expand Down