etnaviv: fix use after free in async shader compile
authorLucas Stach <l.stach@pengutronix.de>
Thu, 14 Jul 2022 08:27:05 +0000 (10:27 +0200)
committerMarge Bot <emma+marge@anholt.net>
Fri, 15 Jul 2022 11:07:12 +0000 (11:07 +0000)
When the shader state is destroyed before the async shader compile is
done, we get a use after free in the async thread, as the shader state
it is operating on is gone. Fix this by dropping any pending job from
the async queue or wait for it to finish before destroying the state
by calling util_queue_drop_job.

Also call util_queue_fence_destroy, which would have caught this issue
by asserting that the queue_fence is in signalled state when the
shader state is destroyed.

Fixes: 1141ed585901 ("etnaviv: async shader compile")
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17534>

src/gallium/drivers/etnaviv/etnaviv_shader.c

index 67268f3..fe028ae 100644 (file)
@@ -511,9 +511,13 @@ etna_create_shader_state(struct pipe_context *pctx,
 static void
 etna_delete_shader_state(struct pipe_context *pctx, void *ss)
 {
+   struct etna_context *ctx = etna_context(pctx);
+   struct etna_screen *screen = ctx->screen;
    struct etna_shader *shader = ss;
    struct etna_shader_variant *v, *t;
 
+   util_queue_drop_job(&screen->shader_compiler_queue, &shader->ready);
+
    v = shader->variants;
    while (v) {
       t = v;
@@ -526,6 +530,7 @@ etna_delete_shader_state(struct pipe_context *pctx, void *ss)
 
    tgsi_free_tokens(shader->tokens);
    ralloc_free(shader->nir);
+   util_queue_fence_destroy(&shader->ready);
    FREE(shader);
 }