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;
 }

-- 


Reply via email to