Skip to content

Commit 1b2c241

Browse files
committed
gfx/vulkan: NULL-check instance_extensions / instance_layers malloc in create_instance_wrapper
vulkan_context_create_instance_wrapper malloc()s two pointer arrays - instance_extensions and instance_layers - then immediately memcpy's into both and assigns them into the VkInstanceCreateInfo that gets passed to vkCreateInstance: const char **instance_extensions = (const char**)malloc(...); const char **instance_layers = (const char**)malloc(...); ... memcpy((void*)instance_extensions, ...); memcpy((void*)instance_layers, ...); info.ppEnabledExtensionNames = instance_extensions; info.ppEnabledLayerNames = instance_layers; Neither malloc is NULL-checked before those memcpys, so an OOM on either one segfaults on the memcpy. An OOM on only one would be caught by the 'end' label free (both frees are there, and free(NULL) is defined as a no-op), but only if we actually reach 'end' rather than crashing on the memcpy. Fix: after both mallocs, NULL-check both and 'goto end' on failure. 'instance' was pre-initialised to VK_NULL_HANDLE at the top of the function, which is the correct error-return value for this API, so the 'end' label cleanup already handles the rest of the function's contract correctly. These allocations are small (pointer arrays sized by the core's extension / layer counts, typically a handful to a few dozen entries), so OOM here is unlikely in practice. Still worth guarding - the payoff for a NULL check against a real crash is asymmetric. Thread-safety: unchanged. Called from the Vulkan context init path which runs on the video thread.
1 parent 1cf6c53 commit 1b2c241

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

gfx/common/vulkan_common.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,18 @@ static VkInstance vulkan_context_create_instance_wrapper(void *opaque, const VkI
902902
const char *required_extensions[3];
903903
uint32_t required_extension_count = 0;
904904

905+
/* Both mallocs must have succeeded before the memcpy / field
906+
* assignments below dereference the buffers. The 'end' label
907+
* free()s both pointers; free(NULL) is a no-op, so if only one
908+
* of the two succeeded it still gets reclaimed. 'instance' was
909+
* pre-initialised to VK_NULL_HANDLE at the top of the function,
910+
* which is the correct error-return value for this API. */
911+
if (!instance_extensions || !instance_layers)
912+
{
913+
RARCH_ERR("[Vulkan] Out of memory allocating instance extension / layer arrays.\n");
914+
goto end;
915+
}
916+
905917
memcpy((void*)instance_extensions, info.ppEnabledExtensionNames, info.enabledExtensionCount * sizeof(const char *));
906918
memcpy((void*)instance_layers, info.ppEnabledLayerNames, info.enabledLayerCount * sizeof(const char *));
907919
info.ppEnabledExtensionNames = instance_extensions;

0 commit comments

Comments
 (0)