Skip to content

Commit

Permalink
drm/i915: Pin pages whilst allocating for dma-buf vmap()
Browse files Browse the repository at this point in the history
During the vmap() routine for the dma-buf, we first grab the pages and
then try to allocate a temporary array to pass to the vmap(). However,
the shrinker can and will reap any object that is unbound if the
allocation for the array first fails. This includes the object which we
are attempting to vmap(). The solution is to mark the object's pages as
pinned whilst we try the allocation to prevent the use-after-free
introduced by the potential shrinkage.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Chris Wilson authored and Daniel Vetter committed Nov 29, 2013
1 parent 0bf2134 commit 993fc6e
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions drivers/gpu/drm/i915/i915_gem_dmabuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,15 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)

ret = i915_gem_object_get_pages(obj);
if (ret)
goto error;
goto err;

i915_gem_object_pin_pages(obj);

ret = -ENOMEM;

pages = drm_malloc_ab(obj->base.size >> PAGE_SHIFT, sizeof(*pages));
if (pages == NULL)
goto error;
goto err_unpin;

i = 0;
for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0)
Expand All @@ -141,15 +143,16 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
drm_free_large(pages);

if (!obj->dma_buf_vmapping)
goto error;
goto err_unpin;

obj->vmapping_count = 1;
i915_gem_object_pin_pages(obj);
out_unlock:
mutex_unlock(&dev->struct_mutex);
return obj->dma_buf_vmapping;

error:
err_unpin:
i915_gem_object_unpin_pages(obj);
err:
mutex_unlock(&dev->struct_mutex);
return ERR_PTR(ret);
}
Expand Down

0 comments on commit 993fc6e

Please sign in to comment.