radv: Fix various non-critical integer overflows
[mesa.git] / src / amd / vulkan / radv_descriptor_set.c
index 8d1343d2d8bb6ec81638d0913f312d451cb9186a..e4634eed6635251f31844c5c742566f7ed4d14b0 100644 (file)
@@ -57,13 +57,14 @@ static int binding_compare(const void* av, const void *bv)
 
 static VkDescriptorSetLayoutBinding *
 create_sorted_bindings(const VkDescriptorSetLayoutBinding *bindings, unsigned count) {
-       VkDescriptorSetLayoutBinding *sorted_bindings = malloc(count * sizeof(VkDescriptorSetLayoutBinding));
+       VkDescriptorSetLayoutBinding *sorted_bindings = malloc(MAX2(count * sizeof(VkDescriptorSetLayoutBinding), 1));
        if (!sorted_bindings)
                return NULL;
 
-       memcpy(sorted_bindings, bindings, count * sizeof(VkDescriptorSetLayoutBinding));
-
-       qsort(sorted_bindings, count, sizeof(VkDescriptorSetLayoutBinding), binding_compare);
+       if (count) {
+               memcpy(sorted_bindings, bindings, count * sizeof(VkDescriptorSetLayoutBinding));
+               qsort(sorted_bindings, count, sizeof(VkDescriptorSetLayoutBinding), binding_compare);
+       }
 
        return sorted_bindings;
 }
@@ -102,8 +103,8 @@ VkResult radv_CreateDescriptorSetLayout(
                }
        }
 
-       uint32_t samplers_offset = sizeof(struct radv_descriptor_set_layout) +
-               (max_binding + 1) * sizeof(set_layout->binding[0]);
+       uint32_t samplers_offset =
+                       offsetof(struct radv_descriptor_set_layout, binding[max_binding + 1]);
        size_t size = samplers_offset + immutable_sampler_count * 4 * sizeof(uint32_t);
        if (ycbcr_sampler_count > 0) {
                size += ycbcr_sampler_count * sizeof(struct radv_sampler_ycbcr_conversion) + (max_binding + 1) * sizeof(uint32_t);
@@ -146,8 +147,6 @@ VkResult radv_CreateDescriptorSetLayout(
        set_layout->has_immutable_samplers = false;
        set_layout->size = 0;
 
-       memset(set_layout->binding, 0, size - sizeof(struct radv_descriptor_set_layout));
-
        uint32_t buffer_count = 0;
        uint32_t dynamic_offset_count = 0;
 
@@ -629,6 +628,23 @@ radv_descriptor_set_destroy(struct radv_device *device,
        vk_free2(&device->vk.alloc, NULL, set);
 }
 
+static void radv_destroy_descriptor_pool(struct radv_device *device,
+                                         const VkAllocationCallbacks *pAllocator,
+                                         struct radv_descriptor_pool *pool)
+{
+       if (!pool->host_memory_base) {
+               for(int i = 0; i < pool->entry_count; ++i) {
+                       radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false);
+               }
+       }
+
+       if (pool->bo)
+               device->ws->buffer_destroy(pool->bo);
+
+       vk_object_base_finish(&pool->base);
+       vk_free2(&device->vk.alloc, pAllocator, pool);
+}
+
 VkResult radv_CreateDescriptorPool(
        VkDevice                                    _device,
        const VkDescriptorPoolCreateInfo*           pCreateInfo,
@@ -721,7 +737,15 @@ VkResult radv_CreateDescriptorPool(
                                                     RADEON_FLAG_READ_ONLY |
                                                     RADEON_FLAG_32BIT,
                                                     RADV_BO_PRIORITY_DESCRIPTOR);
+               if (!pool->bo) {
+                       radv_destroy_descriptor_pool(device, pAllocator, pool);
+                       return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+               }
                pool->mapped_ptr = (uint8_t*)device->ws->buffer_map(pool->bo);
+               if (!pool->mapped_ptr) {
+                       radv_destroy_descriptor_pool(device, pAllocator, pool);
+                       return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+               }
        }
        pool->size = bo_size;
        pool->max_entry_count = pCreateInfo->maxSets;
@@ -741,17 +765,7 @@ void radv_DestroyDescriptorPool(
        if (!pool)
                return;
 
-       if (!pool->host_memory_base) {
-               for(int i = 0; i < pool->entry_count; ++i) {
-                       radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false);
-               }
-       }
-
-       if (pool->bo)
-               device->ws->buffer_destroy(pool->bo);
-
-       vk_object_base_finish(&pool->base);
-       vk_free2(&device->vk.alloc, pAllocator, pool);
+       radv_destroy_descriptor_pool(device, pAllocator, pool);
 }
 
 VkResult radv_ResetDescriptorPool(
@@ -888,23 +902,26 @@ static void write_buffer_descriptor(struct radv_device *device,
        range = align(range, 4);
 
        va += buffer_info->offset + buffer->offset;
-       dst[0] = va;
-       dst[1] = S_008F04_BASE_ADDRESS_HI(va >> 32);
-       dst[2] = range;
-       dst[3] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
-               S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
-               S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
-               S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
+
+       uint32_t rsrc_word3 = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
+                             S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
+                             S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
+                             S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
 
        if (device->physical_device->rad_info.chip_class >= GFX10) {
-               dst[3] |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
-                         S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_RAW) |
-                         S_008F0C_RESOURCE_LEVEL(1);
+               rsrc_word3 |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
+                             S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_RAW) |
+                             S_008F0C_RESOURCE_LEVEL(1);
        } else {
-               dst[3] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
-                         S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
+               rsrc_word3 |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
+                             S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
        }
 
+       dst[0] = va;
+       dst[1] = S_008F04_BASE_ADDRESS_HI(va >> 32);
+       dst[2] = range;
+       dst[3] = rsrc_word3;
+
        if (cmd_buffer)
                radv_cs_add_buffer(device->ws, cmd_buffer->cs, buffer->bo);
        else