From 4cf8edd9bfbded0db401d8ba6c8a087ee4a07ad4 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Thu, 8 Nov 2018 18:23:49 +0100 Subject: [PATCH] vrend: Make sure no stale links to shader programs remain in a sub-context The sub-context holds a pointer to the last shader program used and this is de-referenced , e.g. in vrend_vbo_draw. However, the guest may destroy the program without notifying the sub-context, and as a result the pointer becomes stale and may ber used after free. As a solution add a pointer to the owning context when a program is referenced and if the program gets destroyed, clean the pointer in the sub-context. Closes: #52 Signed-off-by: Gert Wollny Signed-off-by: Dave Airlie --- src/vrend_renderer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index bd76817..7ed0f41 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -296,6 +296,8 @@ struct vrend_linked_shader_program { uint32_t ssbo_used_mask[PIPE_SHADER_TYPES]; GLuint *ssbo_locs[PIPE_SHADER_TYPES]; + + struct vrend_sub_context *ref_context; }; struct vrend_shader { @@ -1462,6 +1464,9 @@ static struct vrend_linked_shader_program *lookup_shader_program(struct vrend_co static void vrend_destroy_program(struct vrend_linked_shader_program *ent) { int i; + if (ent->ref_context && ent->ref_context->prog == ent) + ent->ref_context->prog = NULL; + glDeleteProgram(ent->id); list_del(&ent->head); @@ -3940,6 +3945,7 @@ int vrend_draw_vbo(struct vrend_context *ctx, if (ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]) ctx->sub->prog_ids[PIPE_SHADER_TESS_EVAL] = ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->current->id; ctx->sub->prog = prog; + prog->ref_context = ctx->sub; } } if (!ctx->sub->prog) { @@ -4136,6 +4142,7 @@ void vrend_launch_grid(struct vrend_context *ctx, ctx->sub->prog_ids[PIPE_SHADER_VERTEX] = -1; ctx->sub->prog_ids[PIPE_SHADER_COMPUTE] = ctx->sub->shaders[PIPE_SHADER_COMPUTE]->current->id; ctx->sub->prog = prog; + prog->ref_context = ctx->sub; } ctx->sub->shader_dirty = true; } @@ -5371,6 +5378,9 @@ static void vrend_destroy_sub_context(struct vrend_sub_context *sub) vrend_shader_state_reference(&sub->shaders[PIPE_SHADER_TESS_EVAL], NULL); vrend_shader_state_reference(&sub->shaders[PIPE_SHADER_COMPUTE], NULL); + if (sub->prog) + sub->prog->ref_context = NULL; + vrend_free_programs(sub); for (i = 0; i < PIPE_SHADER_TYPES; i++) { free(sub->consts[i].consts);