gl: remove invalid read and write

Summary:
There could be 2 evas_gl_image referencing 1 evas_gl_texture.
evas_object_image_orient_set could make this case.
In this case, when one evas_gl_image is removed(free), the evas_gl_texture
is not removed because its reference count.
After this point, if the other evas_gl_image is removed without drawing
(see function evas_gl_common_image_draw, line "im->tex->im = im")
then evas_gl_texture is reading invalid adress when it is removed.

Reviewers: Hermet, jsuya, herb, devilhorns

Reviewed By: devilhorns

Subscribers: devilhorns, cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D12229
This commit is contained in:
Shinwoo Kim 2021-01-14 13:47:06 +09:00
parent f6d0bc1b29
commit 34b0d0e973
3 changed files with 14 additions and 5 deletions

View File

@ -723,7 +723,7 @@ Evas_GL_Texture *evas_gl_common_texture_render_noscale_new(Evas_Engine_GL_Conte
Evas_GL_Texture *evas_gl_common_texture_dynamic_new(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
void evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im);
void evas_gl_common_texture_upload(Evas_GL_Texture *tex, RGBA_Image *im, unsigned int bytes_count);
void evas_gl_common_texture_free(Evas_GL_Texture *tex, Eina_Bool force);
Eina_Bool evas_gl_common_texture_free(Evas_GL_Texture *tex, Eina_Bool force);
Evas_GL_Texture *evas_gl_common_texture_alpha_new(Evas_Engine_GL_Context *gc, DATA8 *pixels, unsigned int w, unsigned int h, int fh);
void evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA8 *pixels, unsigned int w, unsigned int h, int fh);
Evas_GL_Texture *evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h);

View File

@ -720,7 +720,15 @@ evas_gl_common_image_free(Evas_GL_Image *im)
{
if (_evas_gl_image_cache_add(im)) return;
}
if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE);
if (im->tex)
{
if (!evas_gl_common_texture_free(im->tex, EINA_TRUE))
{
/* if texture is not freed, we need to assign im to NULL
because after this point im will be freed */
im->tex->im = NULL;
}
}
if (im->im)
evas_cache_image_drop(&im->im->cache_entry);

View File

@ -1550,10 +1550,10 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
im->cache_entry.flags.textured = 1;
}
void
Eina_Bool
evas_gl_common_texture_free(Evas_GL_Texture *tex, Eina_Bool force)
{
if (!tex) return;
if (!tex) return EINA_FALSE;
if (force)
{
evas_gl_preload_pop(tex);
@ -1562,7 +1562,7 @@ evas_gl_common_texture_free(Evas_GL_Texture *tex, Eina_Bool force)
evas_gl_preload_target_unregister(tex, eina_list_data_get(tex->targets));
}
tex->references--;
if (tex->references != 0) return;
if (tex->references != 0) return EINA_FALSE;
if (tex->fglyph)
{
tex->gc->font_glyph_textures_size -= tex->w * tex->h * 4;
@ -1617,6 +1617,7 @@ evas_gl_common_texture_free(Evas_GL_Texture *tex, Eina_Bool force)
}
evas_gl_common_texture_light_free(tex);
return EINA_TRUE;
}
Evas_GL_Texture *