Skip to content

Commit 5a5dc83

Browse files
aizu-mcharles-lunarg
authored andcommitted
clamp emulated property copies to the caller-allocated count
The *2KHR emulation terminators size a temporary array and the caller's output array from the input count, but bound the copy loop by the count the legacy ICD entrypoint writes back. A driver reporting more entries than the caller allocated then copies past both arrays. Snapshot the allocated count before the call and clamp each copy, matching the existing clamp in vkEnumerateDeviceExtensionProperties.
1 parent b52703d commit 5a5dc83

2 files changed

Lines changed: 24 additions & 12 deletions

File tree

loader/terminator.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,8 @@ VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties2(Vk
360360
icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, NULL);
361361
} else {
362362
// Allocate a temporary array for the output of the old function
363-
VkQueueFamilyProperties *properties = loader_stack_alloc(*pQueueFamilyPropertyCount * sizeof(VkQueueFamilyProperties));
363+
uint32_t allocated_count = *pQueueFamilyPropertyCount;
364+
VkQueueFamilyProperties *properties = loader_stack_alloc(allocated_count * sizeof(VkQueueFamilyProperties));
364365
if (properties == NULL) {
365366
*pQueueFamilyPropertyCount = 0;
366367
loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
@@ -371,7 +372,8 @@ VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties2(Vk
371372

372373
icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount,
373374
properties);
374-
for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) {
375+
// The driver reports the written count back in pQueueFamilyPropertyCount; never copy past the array we sized.
376+
for (uint32_t i = 0; i < *pQueueFamilyPropertyCount && i < allocated_count; ++i) {
375377
// Write to the VkQueueFamilyProperties2KHR struct
376378
memcpy(&pQueueFamilyProperties[i].queueFamilyProperties, &properties[i], sizeof(VkQueueFamilyProperties));
377379

@@ -464,7 +466,8 @@ VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperti
464466
pFormatInfo->tiling, pPropertyCount, NULL);
465467
} else {
466468
// Allocate a temporary array for the output of the old function
467-
VkSparseImageFormatProperties *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkSparseImageFormatProperties));
469+
uint32_t allocated_count = *pPropertyCount;
470+
VkSparseImageFormatProperties *properties = loader_stack_alloc(allocated_count * sizeof(VkSparseImageFormatProperties));
468471
if (properties == NULL) {
469472
*pPropertyCount = 0;
470473
loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
@@ -476,7 +479,8 @@ VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperti
476479
icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(
477480
phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage,
478481
pFormatInfo->tiling, pPropertyCount, properties);
479-
for (uint32_t i = 0; i < *pPropertyCount; ++i) {
482+
// The driver reports the written count back in pPropertyCount; never copy past the array we sized.
483+
for (uint32_t i = 0; i < *pPropertyCount && i < allocated_count; ++i) {
480484
// Write to the VkSparseImageFormatProperties2KHR struct
481485
memcpy(&pProperties[i].properties, &properties[i], sizeof(VkSparseImageFormatProperties));
482486

loader/wsi.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,15 +2372,17 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayProperties2KHR
23722372
}
23732373

23742374
// If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayPropertiesKHR and copy it
2375-
VkDisplayPropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayPropertiesKHR));
2375+
uint32_t allocated_count = *pPropertyCount;
2376+
VkDisplayPropertiesKHR *properties = loader_stack_alloc(allocated_count * sizeof(VkDisplayPropertiesKHR));
23762377
if (properties == NULL) {
23772378
return VK_ERROR_OUT_OF_HOST_MEMORY;
23782379
}
23792380
VkResult res = icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, properties);
23802381
if (res < 0) {
23812382
return res;
23822383
}
2383-
for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2384+
// The driver reports the written count back in pPropertyCount; never copy past the array we sized.
2385+
for (uint32_t i = 0; i < *pPropertyCount && i < allocated_count; ++i) {
23842386
memcpy(&pProperties[i].displayProperties, &properties[i], sizeof(VkDisplayPropertiesKHR));
23852387
}
23862388
return res;
@@ -2427,7 +2429,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlanePropertie
24272429
}
24282430

24292431
// If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayPlanePropertiesKHR and copy it
2430-
VkDisplayPlanePropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayPlanePropertiesKHR));
2432+
uint32_t allocated_count = *pPropertyCount;
2433+
VkDisplayPlanePropertiesKHR *properties = loader_stack_alloc(allocated_count * sizeof(VkDisplayPlanePropertiesKHR));
24312434
if (properties == NULL) {
24322435
return VK_ERROR_OUT_OF_HOST_MEMORY;
24332436
}
@@ -2436,7 +2439,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlanePropertie
24362439
if (res < 0) {
24372440
return res;
24382441
}
2439-
for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2442+
// The driver reports the written count back in pPropertyCount; never copy past the array we sized.
2443+
for (uint32_t i = 0; i < *pPropertyCount && i < allocated_count; ++i) {
24402444
memcpy(&pProperties[i].displayPlaneProperties, &properties[i], sizeof(VkDisplayPlanePropertiesKHR));
24412445
}
24422446
return res;
@@ -2484,15 +2488,17 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModeProperties2KHR(VkPhysica
24842488
}
24852489

24862490
// If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayModePropertiesKHR and copy it
2487-
VkDisplayModePropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayModePropertiesKHR));
2491+
uint32_t allocated_count = *pPropertyCount;
2492+
VkDisplayModePropertiesKHR *properties = loader_stack_alloc(allocated_count * sizeof(VkDisplayModePropertiesKHR));
24882493
if (properties == NULL) {
24892494
return VK_ERROR_OUT_OF_HOST_MEMORY;
24902495
}
24912496
VkResult res = icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, properties);
24922497
if (res < 0) {
24932498
return res;
24942499
}
2495-
for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2500+
// The driver reports the written count back in pPropertyCount; never copy past the array we sized.
2501+
for (uint32_t i = 0; i < *pPropertyCount && i < allocated_count; ++i) {
24962502
memcpy(&pProperties[i].displayModeProperties, &properties[i], sizeof(VkDisplayModePropertiesKHR));
24972503
}
24982504
return res;
@@ -2818,14 +2824,16 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(Vk
28182824
NULL);
28192825
} else {
28202826
// Allocate a temporary array for the output of the old function
2821-
VkSurfaceFormatKHR *formats = loader_stack_alloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
2827+
uint32_t allocated_count = *pSurfaceFormatCount;
2828+
VkSurfaceFormatKHR *formats = loader_stack_alloc(allocated_count * sizeof(VkSurfaceFormatKHR));
28222829
if (formats == NULL) {
28232830
return VK_ERROR_OUT_OF_HOST_MEMORY;
28242831
}
28252832

28262833
VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface,
28272834
pSurfaceFormatCount, formats);
2828-
for (uint32_t i = 0; i < *pSurfaceFormatCount; ++i) {
2835+
// The driver reports the written count back in pSurfaceFormatCount; never copy past the array we sized.
2836+
for (uint32_t i = 0; i < *pSurfaceFormatCount && i < allocated_count; ++i) {
28292837
pSurfaceFormats[i].surfaceFormat = formats[i];
28302838
if (pSurfaceFormats[i].pNext != NULL) {
28312839
loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,

0 commit comments

Comments
 (0)