From e92b9c5f4fceb3171f7d09c85052decaab6a95f4 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Tue, 8 Oct 2019 23:24:02 +0200 Subject: [PATCH] radv: Check the size of the imported buffer. This is a security feature to disallow malicious apps from passing a buffer that is too small. Reviewed-by: Samuel Pitoiset --- src/amd/vulkan/radv_android.c | 15 ++++++++++++++- src/amd/vulkan/radv_device.c | 2 +- src/amd/vulkan/radv_radeon_winsys.h | 3 ++- src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c | 7 ++++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/amd/vulkan/radv_android.c b/src/amd/vulkan/radv_android.c index 8716c4f4660..cd4587d5af1 100644 --- a/src/amd/vulkan/radv_android.c +++ b/src/amd/vulkan/radv_android.c @@ -642,8 +642,9 @@ radv_import_ahb_memory(struct radv_device *device, if (dma_buf < 0) return VK_ERROR_INVALID_EXTERNAL_HANDLE; + uint64_t alloc_size = 0; mem->bo = device->ws->buffer_from_fd(device->ws, dma_buf, - priority); + priority, &alloc_size); if (!mem->bo) return VK_ERROR_OUT_OF_HOST_MEMORY; @@ -662,6 +663,18 @@ radv_import_ahb_memory(struct radv_device *device, mem->bo = NULL; return result; } + + if (alloc_size < mem->image->size) { + device->ws->buffer_destroy(mem->bo); + mem->bo = NULL; + return VK_ERROR_INVALID_EXTERNAL_HANDLE; + } + } else if (mem->buffer) { + if (alloc_size < mem->buffer->size) { + device->ws->buffer_destroy(mem->bo); + mem->bo = NULL; + return VK_ERROR_INVALID_EXTERNAL_HANDLE; + } } /* "If the vkAllocateMemory command succeeds, the implementation must diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index b44b5cc6a9d..582ab228802 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -3523,7 +3523,7 @@ static VkResult radv_alloc_memory(struct radv_device *device, import_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT); mem->bo = device->ws->buffer_from_fd(device->ws, import_info->fd, - priority); + priority, NULL); if (!mem->bo) { result = VK_ERROR_INVALID_EXTERNAL_HANDLE; goto fail; diff --git a/src/amd/vulkan/radv_radeon_winsys.h b/src/amd/vulkan/radv_radeon_winsys.h index 20876807662..ba464dea884 100644 --- a/src/amd/vulkan/radv_radeon_winsys.h +++ b/src/amd/vulkan/radv_radeon_winsys.h @@ -243,7 +243,8 @@ struct radeon_winsys { struct radeon_winsys_bo *(*buffer_from_fd)(struct radeon_winsys *ws, int fd, - unsigned priority); + unsigned priority, + uint64_t *alloc_size); bool (*buffer_get_fd)(struct radeon_winsys *ws, struct radeon_winsys_bo *bo, diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c index d75c1287094..d59365b9286 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c @@ -533,7 +533,8 @@ error: static struct radeon_winsys_bo * radv_amdgpu_winsys_bo_from_fd(struct radeon_winsys *_ws, - int fd, unsigned priority) + int fd, unsigned priority, + uint64_t *alloc_size) { struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws); struct radv_amdgpu_winsys_bo *bo; @@ -556,6 +557,10 @@ radv_amdgpu_winsys_bo_from_fd(struct radeon_winsys *_ws, if (r) goto error_query; + if (alloc_size) { + *alloc_size = info.alloc_size; + } + r = amdgpu_va_range_alloc(ws->dev, amdgpu_gpu_va_range_general, result.alloc_size, 1 << 20, 0, &va, &va_handle, AMDGPU_VA_RANGE_HIGH); -- 2.30.2