From 0ea386128b8fe4a4c0dc32101c4d4dd565723341 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 4 Apr 2019 11:18:26 +1000 Subject: [PATCH] iris: avoid use after free in shader destruction While playing with compute shaders, I was getting a random crash, noticed that bind_state was using the old shader info for comparision, but gallium allows the shader to be deleted while bound, so this could lead to a use after free. This can't happen using the cso cache. As it tracks all of this. Reviewed-by: Kenneth Graunke --- src/gallium/drivers/iris/iris_program.c | 56 +++++++++++++++++++++---- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c index ebddcc2fb58..3ac917c6e76 100644 --- a/src/gallium/drivers/iris/iris_program.c +++ b/src/gallium/drivers/iris/iris_program.c @@ -1620,14 +1620,56 @@ iris_create_compute_state(struct pipe_context *ctx, * Frees the iris_uncompiled_shader. */ static void -iris_delete_shader_state(struct pipe_context *ctx, void *state) +iris_delete_shader_state(struct pipe_context *ctx, void *state, gl_shader_stage stage) { struct iris_uncompiled_shader *ish = state; + struct iris_context *ice = (void *) ctx; + + if (ice->shaders.uncompiled[stage] == ish) { + ice->shaders.uncompiled[stage] = NULL; + ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_VS << stage; + } ralloc_free(ish->nir); free(ish); } +static void +iris_delete_vs_state(struct pipe_context *ctx, void *state) +{ + iris_delete_shader_state(ctx, state, MESA_SHADER_VERTEX); +} + +static void +iris_delete_tcs_state(struct pipe_context *ctx, void *state) +{ + iris_delete_shader_state(ctx, state, MESA_SHADER_TESS_CTRL); +} + +static void +iris_delete_tes_state(struct pipe_context *ctx, void *state) +{ + iris_delete_shader_state(ctx, state, MESA_SHADER_TESS_EVAL); +} + +static void +iris_delete_gs_state(struct pipe_context *ctx, void *state) +{ + iris_delete_shader_state(ctx, state, MESA_SHADER_GEOMETRY); +} + +static void +iris_delete_fs_state(struct pipe_context *ctx, void *state) +{ + iris_delete_shader_state(ctx, state, MESA_SHADER_FRAGMENT); +} + +static void +iris_delete_cs_state(struct pipe_context *ctx, void *state) +{ + iris_delete_shader_state(ctx, state, MESA_SHADER_COMPUTE); +} + /** * The pipe->bind_[stage]_state() driver hook. * @@ -1737,12 +1779,12 @@ iris_init_program_functions(struct pipe_context *ctx) ctx->create_fs_state = iris_create_fs_state; ctx->create_compute_state = iris_create_compute_state; - ctx->delete_vs_state = iris_delete_shader_state; - ctx->delete_tcs_state = iris_delete_shader_state; - ctx->delete_tes_state = iris_delete_shader_state; - ctx->delete_gs_state = iris_delete_shader_state; - ctx->delete_fs_state = iris_delete_shader_state; - ctx->delete_compute_state = iris_delete_shader_state; + ctx->delete_vs_state = iris_delete_vs_state; + ctx->delete_tcs_state = iris_delete_tcs_state; + ctx->delete_tes_state = iris_delete_tes_state; + ctx->delete_gs_state = iris_delete_gs_state; + ctx->delete_fs_state = iris_delete_fs_state; + ctx->delete_compute_state = iris_delete_cs_state; ctx->bind_vs_state = iris_bind_vs_state; ctx->bind_tcs_state = iris_bind_tcs_state; -- 2.30.2