[Mesa-dev] [PATCH v3 07/18] anv/allocator: Add a BO cache

Jason Ekstrand jason at jlekstrand.net
Mon Apr 3 23:30:10 UTC 2017


On Mon, Apr 3, 2017 at 4:26 PM, Chad Versace <chadversary at chromium.org>
wrote:

> On Wed 15 Mar 2017, Jason Ekstrand wrote:
> > This cache allows us to easily ensure that we have a unique anv_bo for
> > each gem handle.  We'll need this in order to support multiple-import of
> > memory objects and semaphores.
> >
> > v2 (Jason Ekstrand):
> >  - Reject BO imports if the size doesn't match the prime fd size as
> >    reported by lseek().
> >
> > v3 (Jason Ekstrand):
> >  - Fix reference counting around cache_release (Chris Willson)
> >  - Move the mutex_unlock() later in cache_release
> > ---
> >  src/intel/vulkan/anv_allocator.c | 261 ++++++++++++++++++++++++++++++
> +++++++++
> >  src/intel/vulkan/anv_private.h   |  26 ++++
> >  2 files changed, 287 insertions(+)
>
>
>
> > +VkResult
> > +anv_bo_cache_import(struct anv_device *device,
> > +                    struct anv_bo_cache *cache,
> > +                    int fd, uint64_t size, struct anv_bo **bo_out,
> > +                    VkAllocationCallbacks *alloc)
> > +{
> > +   pthread_mutex_lock(&cache->mutex);
> > +
> > +   /* The kernel is going to give us whole pages anyway */
> > +   size = align_u64(size, 4096);
> > +
> > +   uint32_t gem_handle = anv_gem_fd_to_handle(device, fd);
> > +   if (!gem_handle) {
> > +      pthread_mutex_unlock(&cache->mutex);
> > +      return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX);
> > +   }
> > +
> > +   struct anv_cached_bo *bo = anv_bo_cache_lookup_locked(cache,
> gem_handle);
> > +   if (bo) {
> > +      assert(bo->bo.size == size);
>
> For security's sake, we must always check the size, even if the bo is in
> the cache. An assertion isn't enough. A malicious client may tell the
> truth the first time when sending the fd to the trusted app. The
> malicious client may then dup the fd and send it to the trusted app with
> a false size.
>

Yup.  Fixed locally.

--Jason


> > +      __sync_fetch_and_add(&bo->refcount, 1);
> > +   } else {
> > +      /* For security purposes, we reject BO imports where the size
> does not
> > +       * match exactly.  This prevents a malicious client from passing a
> > +       * buffer to a trusted client, lying about the size, and telling
> the
> > +       * trusted client to try and texture from an image that goes
> > +       * out-of-bounds.  This sort of thing could lead to GPU hangs or
> worse
> > +       * in the trusted client.  The trusted client can protect itself
> against
> > +       * this sort of attack but only if it can trust the buffer size.
> > +       */
>
> > +      off_t import_size = lseek(fd, 0, SEEK_END);
> > +      if (import_size == (off_t)-1 || import_size != size) {
> > +         anv_gem_close(device, gem_handle);
> > +         pthread_mutex_unlock(&cache->mutex);
> > +         return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX);
> > +      }
> > +
> > +      struct anv_cached_bo *bo =
> > +         vk_alloc(alloc, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
> > +      if (!bo) {
> > +         anv_gem_close(device, gem_handle);
> > +         pthread_mutex_unlock(&cache->mutex);
> > +         return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
> > +      }
> > +
> > +      bo->refcount = 1;
> > +
> > +      anv_bo_init(&bo->bo, gem_handle, size);
> > +
> > +      _mesa_hash_table_insert(cache->bo_map, (void
> *)(uintptr_t)gem_handle, bo);
> > +   }
> > +
> > +   pthread_mutex_unlock(&cache->mutex);
> > +
> > +   /* From the Vulkan spec:
> > +    *
> > +    *    "Importing memory from a file descriptor transfers ownership of
> > +    *    the file descriptor from the application to the Vulkan
> > +    *    implementation. The application must not perform any
> operations on
> > +    *    the file descriptor after a successful import."
> > +    *
> > +    * If the import fails, we leave the file descriptor open.
> > +    */
> > +   close(fd);
> > +
> > +   *bo_out = &bo->bo;
> > +
> > +   return VK_SUCCESS;
> > +}
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170403/a984d6eb/attachment.html>


More information about the mesa-dev mailing list