Skip to content

Commit

Permalink
drm/v3d: Fix a use-after-free race accessing the scheduler's fences.
Browse files Browse the repository at this point in the history
Once we push the job, the scheduler could run it and free it.  So, if
we want to reference their fences, we need to grab them before then.
I haven't seen this happen in many days of conformance test runtime,
but let's still close the race.

Signed-off-by: Eric Anholt <eric@anholt.net>
Fixes: 57692c9 ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+")
Link: https://patchwork.freedesktop.org/patch/254119/
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
  • Loading branch information
Eric Anholt committed Oct 15, 2018
1 parent 7323001 commit 34c2c4f
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 2 deletions.
5 changes: 5 additions & 0 deletions drivers/gpu/drm/v3d/v3d_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ struct v3d_exec_info {
*/
struct dma_fence *bin_done_fence;

/* Fence for when the scheduler considers the render to be
* done, for when the BOs reservations should be complete.
*/
struct dma_fence *render_done_fence;

struct kref refcount;

/* This is the array of BOs that were looked up at the start of exec. */
Expand Down
8 changes: 6 additions & 2 deletions drivers/gpu/drm/v3d/v3d_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ v3d_flush_caches(struct v3d_dev *v3d)
static void
v3d_attach_object_fences(struct v3d_exec_info *exec)
{
struct dma_fence *out_fence = &exec->render.base.s_fence->finished;
struct dma_fence *out_fence = exec->render_done_fence;
struct v3d_bo *bo;
int i;

Expand Down Expand Up @@ -409,6 +409,7 @@ v3d_exec_cleanup(struct kref *ref)
dma_fence_put(exec->render.done_fence);

dma_fence_put(exec->bin_done_fence);
dma_fence_put(exec->render_done_fence);

for (i = 0; i < exec->bo_count; i++)
drm_gem_object_put_unlocked(&exec->bo[i]->base);
Expand Down Expand Up @@ -572,6 +573,9 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
if (ret)
goto fail_unreserve;

exec->render_done_fence =
dma_fence_get(&exec->render.base.s_fence->finished);

kref_get(&exec->refcount); /* put by scheduler job completion */
drm_sched_entity_push_job(&exec->render.base,
&v3d_priv->sched_entity[V3D_RENDER]);
Expand All @@ -585,7 +589,7 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
sync_out = drm_syncobj_find(file_priv, args->out_sync);
if (sync_out) {
drm_syncobj_replace_fence(sync_out, 0,
&exec->render.base.s_fence->finished);
exec->render_done_fence);
drm_syncobj_put(sync_out);
}

Expand Down

0 comments on commit 34c2c4f

Please sign in to comment.