diff options
author | Shinwoo Kim <cinoo.kim@samsung.com> | 2021-01-14 13:47:06 +0900 |
---|---|---|
committer | Shinwoo Kim <cinoo.kim@samsung.com> | 2021-01-14 13:47:26 +0900 |
commit | 34b0d0e973274c1a3df2386a30ad2a31bfcfe0d7 (patch) | |
tree | 42662b9eff9661e05779d7337e493f8e3a30ddfa | |
parent | f6d0bc1b2980098859f6181bf823c6b627ae6a5b (diff) | |
download | efl-34b0d0e973274c1a3df2386a30ad2a31bfcfe0d7.tar.gz |
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
-rw-r--r-- | src/modules/evas/engines/gl_common/evas_gl_common.h | 2 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_common/evas_gl_image.c | 10 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_common/evas_gl_texture.c | 7 |
3 files changed, 14 insertions, 5 deletions
diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index c7b4d22150..2d9d825a75 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -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); diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c index 2d9383305a..13ca077cac 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_image.c +++ b/src/modules/evas/engines/gl_common/evas_gl_image.c @@ -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); diff --git a/src/modules/evas/engines/gl_common/evas_gl_texture.c b/src/modules/evas/engines/gl_common/evas_gl_texture.c index 47dd8305a8..049e4236cb 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_texture.c +++ b/src/modules/evas/engines/gl_common/evas_gl_texture.c @@ -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 * |