vbo: fix out-of-bounds array access
authorBrian Paul <brianp@vmware.com>
Thu, 5 Nov 2009 00:51:21 +0000 (17:51 -0700)
committerBrian Paul <brianp@vmware.com>
Thu, 5 Nov 2009 00:51:28 +0000 (17:51 -0700)
The exec->vtx.inputs[] array was being written past its end.  This was
clobbering the following vbo_exec_context::eval state.  Probably not noticed
since evaluators and immediate mode rendering don't happen at the same time.

Fixed the loop in vbo_exec_vtx_init().
Changed the size of the vbo_exec_context::vtx.arrays[] array.
Added a bunch of debug-build assertions.

Issue found by Vinson Lee.

src/mesa/vbo/vbo_exec.h
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_exec_draw.c

index e0f44892cff7a8c5861393365a310729c0bd7621..7fb59261600dab067329ca9e5400155c1f4c7b6b 100644 (file)
@@ -103,7 +103,7 @@ struct vbo_exec_context
       GLubyte active_sz[VBO_ATTRIB_MAX];
 
       GLfloat *attrptr[VBO_ATTRIB_MAX]; 
-      struct gl_client_array arrays[VBO_ATTRIB_MAX];
+      struct gl_client_array arrays[VERT_ATTRIB_MAX];
 
       /* According to program mode, the values above plus current
        * values are squashed down to the 32 attributes passed to the
index 387d4ee3d4a0337c6dec2e9289d1724a0e2eb184..acc76479002fa3bc44ca630a57ce609e1dbd1aa7 100644 (file)
@@ -695,8 +695,14 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
    _mesa_install_exec_vtxfmt( exec->ctx, &exec->vtxfmt );
 
    for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
+      ASSERT(i < Elements(exec->vtx.attrsz));
       exec->vtx.attrsz[i] = 0;
+      ASSERT(i < Elements(exec->vtx.active_sz));
       exec->vtx.active_sz[i] = 0;
+   }
+   for (i = 0 ; i < VERT_ATTRIB_MAX; i++) {
+      ASSERT(i < Elements(exec->vtx.inputs));
+      ASSERT(i < Elements(exec->vtx.arrays));
       exec->vtx.inputs[i] = &exec->vtx.arrays[i];
    }
    
index 0c258c535e07aad67814971f0d5275638119ffdc..f41d629450702107bd2519f3efca07b23ebe7270 100644 (file)
@@ -172,6 +172,7 @@ vbo_exec_bind_arrays( GLcontext *ctx )
          exec->vtx.inputs[attr] = &vbo->legacy_currval[attr];
       }
       for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) {
+         ASSERT(attr + 16 < Elements(exec->vtx.inputs));
          exec->vtx.inputs[attr + 16] = &vbo->mat_currval[attr];
       }
       map = vbo->map_vp_none;
@@ -184,6 +185,7 @@ vbo_exec_bind_arrays( GLcontext *ctx )
        */
       for (attr = 0; attr < 16; attr++) {
          exec->vtx.inputs[attr] = &vbo->legacy_currval[attr];
+         ASSERT(attr + 16 < Elements(exec->vtx.inputs));
          exec->vtx.inputs[attr + 16] = &vbo->generic_currval[attr];
       }
       map = vbo->map_vp_arb;
@@ -212,6 +214,8 @@ vbo_exec_bind_arrays( GLcontext *ctx )
 
       if (exec->vtx.attrsz[src]) {
          /* override the default array set above */
+         ASSERT(attr < Elements(exec->vtx.inputs));
+         ASSERT(attr < Elements(exec->vtx.arrays)); /* arrays[] */
          exec->vtx.inputs[attr] = &arrays[attr];
 
          if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {