jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=d69f9e0b84f0e3827fbee328fc4a6a46e499faf6
commit d69f9e0b84f0e3827fbee328fc4a6a46e499faf6 Author: Jean-Philippe Andre <jp.an...@samsung.com> Date: Mon Aug 31 17:28:58 2015 +0900 Evas masking: Fix potential invalid access to mask image After clip_image_get, the old mask may be replaced by a new one, and unref'ed, but it is later on set back as the context mask image. Maybe it's possible that there was 0 reference and the image got freed in between. No idea how to test this. @fix --- src/lib/evas/canvas/evas_render.c | 4 ++++ src/lib/evas/filters/evas_filter.c | 10 +++++++++- src/lib/evas/include/evas_private.h | 2 +- src/modules/evas/engines/gl_generic/evas_engine.c | 8 +++++++- src/modules/evas/engines/software_generic/evas_engine.c | 16 +++++++++++++++- 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index 0618e1a..faa56c5 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -1559,6 +1559,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, e->engine.func->context_clip_unset(e->engine.data.output, context); e->engine.func->context_clip_image_set (e->engine.data.output, context, oldm_sfc, oldm_x, oldm_y, e, do_async); + /* unref image since clip_image_get refs it */ + if (oldm_sfc) e->engine.func->image_free(e->engine.data.output, oldm_sfc); } // FIXME: needs to cache these maps and @@ -1694,6 +1696,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, e->engine.func->context_clip_unset(e->engine.data.output, ctx); e->engine.func->context_clip_image_set (e->engine.data.output, ctx, oldm_sfc, oldm_x, oldm_y, e, do_async); + /* unref image since clip_image_get refs it */ + if (oldm_sfc) e->engine.func->image_free(e->engine.data.output, oldm_sfc); } if (!use_mapped_ctx) e->engine.func->context_free(e->engine.data.output, ctx); diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index 5499608..bd2ccfc 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -263,6 +263,9 @@ evas_filter_context_destroy(Evas_Filter_Context *ctx) EINA_INLIST_FREE(ctx->commands, cmd) _command_del(ctx, cmd); + if (ctx->target.mask) + ctx->evas->engine.func->image_free(ctx->evas->engine.data.output, ctx->target.mask); + free(ctx); } @@ -1497,6 +1500,8 @@ Eina_Bool evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, void *surface, int x, int y) { + void *mask = NULL; + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); ctx->target.bufid = evas_filter_buffer_image_new(ctx, surface); @@ -1513,7 +1518,10 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, ctx->target.color_use = EINA_FALSE; ENFN->context_clip_image_get - (ENDT, draw_context, &ctx->target.mask, &ctx->target.mask_x, &ctx->target.mask_y); + (ENDT, draw_context, &mask, &ctx->target.mask_x, &ctx->target.mask_y); + if (ctx->target.mask) + ctx->evas->engine.func->image_free(ctx->evas->engine.data.output, ctx->target.mask); + ctx->target.mask = mask; if (ctx->gl_engine) { diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index f4e019e..f513be4 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1268,7 +1268,7 @@ struct _Evas_Func void (*context_clip_set) (void *data, void *context, int x, int y, int w, int h); void (*context_clip_image_set) (void *data, void *context, void *surface, int x, int y, Evas_Public_Data *evas, Eina_Bool do_async); void (*context_clip_image_unset) (void *data, void *context); - void (*context_clip_image_get) (void *data, void *context, void **surface, int *x, int *y); + void (*context_clip_image_get) (void *data, void *context, void **surface, int *x, int *y); /* incref surface if not NULL */ void (*context_clip_clip) (void *data, void *context, int x, int y, int w, int h); void (*context_clip_unset) (void *data, void *context); int (*context_clip_get) (void *data, void *context, int *x, int *y, int *w, int *h); diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 8211bb6..9d93c43 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -2160,7 +2160,13 @@ eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int { RGBA_Draw_Context *ctx = context; - if (ie) *ie = ctx->clip.mask; + if (ie) + { + Evas_GL_Image *im = ctx->clip.mask; + + *ie = im; + if (im) evas_gl_common_image_ref(im); + } if (x) *x = ctx->clip.mask_x; if (y) *y = ctx->clip.mask_y; } diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index cdaba07..3315fef 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -511,7 +511,21 @@ eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int { RGBA_Draw_Context *ctx = context; - if (ie) *ie = ctx->clip.mask; + if (ie) + { + Image_Entry *im = ctx->clip.mask; + + *ie = im; + if (im) + { +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + evas_cache2_image_ref(im); + else +#endif + evas_cache_image_ref(im); + } + } if (x) *x = ctx->clip.mask_x; if (y) *y = ctx->clip.mask_y; } --