r300: Increase reference count of texture objects referenced by current state.
authorMichel Dänzer <daenzer@vmware.com>
Thu, 30 Apr 2009 11:21:08 +0000 (13:21 +0200)
committerMichel Dänzer <daenzer@vmware.com>
Thu, 30 Apr 2009 11:21:08 +0000 (13:21 +0200)
Fixes a use-after-free reported in
http://bugs.freedesktop.org/show_bug.cgi?id=20539, so this possibly fixes that
bug. It has been confirmed to fix
http://bugs.freedesktop.org/show_bug.cgi?id=17895 .

src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/r300/r300_texmem.c
src/mesa/drivers/dri/r300/r300_texstate.c

index 9c4958699841ef22895d8d961b6b6a9ed9d3cab5..96a3205f1a3be5d38aed182ac905aa2813220042 100644 (file)
@@ -215,7 +215,7 @@ struct r300_tex_obj {
 };
 
 struct r300_texture_env_state {
-       r300TexObjPtr texobj;
+       struct gl_texture_object *texobj;
        GLenum format;
        GLenum envMode;
 };
index 6b79aa4313a7d09cb84a6b556b37576572124cfe..79f0b3625ca8228ebd6b9a722fc3d2b5e6f445e3 100644 (file)
@@ -1362,7 +1362,7 @@ static void r300SetupTextures(GLcontext * ctx)
 #endif
                        tmu_mappings[i] = hw_tmu;
 
-                       t = r300->state.texture.unit[i].texobj;
+                       t = (r300TexObjPtr) r300->state.texture.unit[i].texobj->DriverData;
                        /* XXX questionable fix for bug 9170: */
                        if (!t)
                                continue;
index 0fe51b0c680e1ec8762d2bccd1dffb070de5b06f..a89ab83d948a7009c6f16228541f31f4baccba1e 100644 (file)
@@ -44,6 +44,7 @@ SOFTWARE.
 #include "main/colormac.h"
 #include "main/macros.h"
 #include "main/simple_list.h"
+#include "main/texobj.h"
 #include "radeon_reg.h"                /* gets definition for usleep */
 #include "r300_context.h"
 #include "r300_state.h"
@@ -71,8 +72,8 @@ void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t)
        }
 
        for (i = 0; i < rmesa->radeon.glCtx->Const.MaxTextureUnits; i++) {
-               if (rmesa->state.texture.unit[i].texobj == t) {
-                       rmesa->state.texture.unit[i].texobj = NULL;
+               if (rmesa->state.texture.unit[i].texobj == t->base.tObj) {
+                       _mesa_reference_texobj(&rmesa->state.texture.unit[i].texobj, NULL);
                }
        }
 }
index cadec7f3ecf433212ee948fdca7d5a2456a83750..abe613e27bce12d6d98a24340b73e758260307a6 100644 (file)
@@ -567,19 +567,20 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
        /* Update state if this is a different texture object to last
         * time.
         */
-       if (rmesa->state.texture.unit[unit].texobj != t) {
+       if (rmesa->state.texture.unit[unit].texobj != tObj) {
                if (rmesa->state.texture.unit[unit].texobj != NULL) {
+                       r300TexObjPtr t_old = (r300TexObjPtr) rmesa->state.texture.unit[unit].texobj->DriverData;
+
                        /* The old texture is no longer bound to this texture unit.
                         * Mark it as such.
                         */
 
-                       rmesa->state.texture.unit[unit].texobj->base.bound &=
-                           ~(1 << unit);
+                       t_old->base.bound &= ~(1 << unit);
                }
 
-               rmesa->state.texture.unit[unit].texobj = t;
+               _mesa_reference_texobj(&rmesa->state.texture.unit[unit].texobj, tObj);
                t->base.bound |= (1 << unit);
-               driUpdateTextureLRU((driTextureObject *) t);    /* XXX: should be locked! */
+               driUpdateTextureLRU(&t->base);  /* XXX: should be locked! */
        }
 
        return !t->border_fallback;