radv: Check the size of the imported buffer.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Tue, 8 Oct 2019 21:24:02 +0000 (23:24 +0200)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Thu, 10 Oct 2019 17:02:34 +0000 (17:02 +0000)
This is a security feature to disallow malicious apps from passing
a buffer that is too small.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
src/amd/vulkan/radv_android.c
src/amd/vulkan/radv_device.c
src/amd/vulkan/radv_radeon_winsys.h
src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c

index 8716c4f4660abf7ee7e47c81b06633ed0dfad9ae..cd4587d5af14cae068d4ebc076239edd0bbca7e7 100644 (file)
@@ -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
index b44b5cc6a9d314a3e1ff5f3d33dff18c044ed30b..582ab228802c7b2f7bf5d2bfbc32f5abd2737c7b 100644 (file)
@@ -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;
index 20876807662a59192860fb2ade6ca3bf476aec80..ba464dea88468ed59be5016517e2d9f3e1600aec 100644 (file)
@@ -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,
index d75c12870945d035a72e45d21511b1bc0e1ddc76..d59365b9286f466a0aeb3371c85f460442307508 100644 (file)
@@ -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);