aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/vbo/vbo_exec.c
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2013-04-24 01:29:26 +0200
committerMarek Olšák <[email protected]>2013-05-01 20:08:53 +0200
commit8eef6ad2e2f90feac231a2e09ed4765f23ed1557 (patch)
tree36bdf18ebe5d9152e92f406fe1dc4bf00192bc39 /src/mesa/vbo/vbo_exec.c
parentb5b6460c40e1c46f6af6a490485132ea0864572c (diff)
vbo: fix possible use-after-free segfault after a VAO is deleted
This like the fifth attempt to fix the issue. Also with the new "validating" flag, we can set recalculate_inputs to FALSE earlier in vbo_bind_arrays, because _mesa_update_state won't change it. NOTE: This is a candidate for the stable branches. v2: fixed a typo Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/mesa/vbo/vbo_exec.c')
-rw-r--r--src/mesa/vbo/vbo_exec.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/mesa/vbo/vbo_exec.c b/src/mesa/vbo/vbo_exec.c
index 0a8fbf8ede1..926e7b46ddb 100644
--- a/src/mesa/vbo/vbo_exec.c
+++ b/src/mesa/vbo/vbo_exec.c
@@ -80,10 +80,26 @@ void vbo_exec_destroy( struct gl_context *ctx )
*/
void vbo_exec_invalidate_state( struct gl_context *ctx, GLuint new_state )
{
- struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
+ struct vbo_context *vbo = vbo_context(ctx);
+ struct vbo_exec_context *exec = &vbo->exec;
- if (new_state & (_NEW_PROGRAM|_NEW_ARRAY)) {
+ if (!exec->validating && new_state & (_NEW_PROGRAM|_NEW_ARRAY)) {
exec->array.recalculate_inputs = GL_TRUE;
+
+ /* If we ended up here because a VAO was deleted, the _DrawArrays
+ * pointer which pointed to the VAO might be invalid now, so set it
+ * to NULL. This prevents crashes in driver functions like Clear
+ * where driver state validation might occur, but the vbo module is
+ * still in an invalid state.
+ *
+ * Drivers should skip vertex array state validation if _DrawArrays
+ * is NULL. It also has no effect on performance, because attrib
+ * bindings will be recalculated anyway.
+ */
+ if (vbo->last_draw_method == DRAW_ARRAYS) {
+ ctx->Array._DrawArrays = NULL;
+ vbo->last_draw_method = DRAW_NONE;
+ }
}
if (new_state & _NEW_EVAL)