summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Neph <ryanneph@google.com>2023-09-15 17:06:57 -0700
committerMarge Bot <emma+marge@anholt.net>2023-09-18 23:09:58 +0000
commitd584798ca648e44aa9b6a089d9d6ecb244415d53 (patch)
tree616829b83e55b59241735aeccbb30c1de1ee83f1
parentbaa5528131c3c110d241bd4b5c25160fab19952a (diff)
vkr: validate queueCount at device creation
Signed-off-by: Ryan Neph <ryanneph@google.com> Part-of: <https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/1239>
-rw-r--r--src/venus/vkr_device.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/venus/vkr_device.c b/src/venus/vkr_device.c
index c6a77b7..4e9a6da 100644
--- a/src/venus/vkr_device.c
+++ b/src/venus/vkr_device.c
@@ -84,6 +84,46 @@ vkr_dispatch_vkCreateDevice(struct vn_dispatch_context *dispatch,
struct vkr_physical_device *physical_dev =
vkr_physical_device_from_handle(args->physicalDevice);
+ /* there can be at most two members sharing a queueFamilyIndex (one
+ * protected-capable, one not), in which case their summed queueCount must
+ * be <= the family's VkQueueFamilyProperties::queueCount.
+ */
+ {
+ uint32_t *counts =
+ malloc(sizeof(uint32_t) * physical_dev->queue_family_property_count);
+ if (!counts) {
+ args->ret = VK_ERROR_OUT_OF_HOST_MEMORY;
+ return;
+ }
+ memset(counts, 0, sizeof(uint32_t) * physical_dev->queue_family_property_count);
+
+ args->ret = VK_SUCCESS;
+ for (uint32_t i = 0; i < args->pCreateInfo->queueCreateInfoCount; i++) {
+ const uint32_t queue_family_index =
+ args->pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex;
+ const uint32_t queue_count = args->pCreateInfo->pQueueCreateInfos[i].queueCount;
+
+ if (queue_family_index >= physical_dev->queue_family_property_count) {
+ args->ret = VK_ERROR_UNKNOWN;
+ break;
+ }
+
+ const VkQueueFamilyProperties *queue_family_properties =
+ &physical_dev->queue_family_properties[queue_family_index];
+
+ if (queue_family_properties->queueCount - counts[queue_family_index] <
+ queue_count) {
+ args->ret = VK_ERROR_UNKNOWN;
+ break;
+ }
+ counts[queue_family_index] += queue_count;
+ }
+
+ free(counts);
+ if (args->ret != VK_SUCCESS)
+ return;
+ }
+
/* append extensions for our own use */
const char **exts = NULL;
uint32_t ext_count = args->pCreateInfo->enabledExtensionCount;