r300: Increase reference count of texture objects referenced by current state.

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 .
This commit is contained in:
Michel Dänzer
2009-04-30 13:21:08 +02:00
parent ba27fe3710
commit c28707b507
4 changed files with 11 additions and 9 deletions
+1 -1
View 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;
};
+1 -1
View 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;
+3 -2
View 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);
}
}
}
+6 -5
View 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;