diff options
Diffstat (limited to 'yocto-poky/meta/recipes-gnome/librsvg/librsvg/CVE-2015-7558_3.patch')
-rw-r--r-- | yocto-poky/meta/recipes-gnome/librsvg/librsvg/CVE-2015-7558_3.patch | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/yocto-poky/meta/recipes-gnome/librsvg/librsvg/CVE-2015-7558_3.patch b/yocto-poky/meta/recipes-gnome/librsvg/librsvg/CVE-2015-7558_3.patch new file mode 100644 index 000000000..dd67ab768 --- /dev/null +++ b/yocto-poky/meta/recipes-gnome/librsvg/librsvg/CVE-2015-7558_3.patch @@ -0,0 +1,223 @@ +From a51919f7e1ca9c535390a746fbf6e28c8402dc61 Mon Sep 17 00:00:00 2001 +From: Benjamin Otte <otte@redhat.com> +Date: Wed, 7 Oct 2015 08:45:37 +0200 +Subject: [PATCH] rsvg: Add rsvg_acquire_node() + +This function does proper recursion checks when looking up resources +from URLs and thereby helps avoiding infinite loops when cyclic +references span multiple types of elements. + +Upstream-status: Backport + +https://git.gnome.org/browse/librsvg/commit/rsvg-styles.c?id=a51919f7e1ca9c535390a746fbf6e28c8402dc61 + +CVE: CVE-2015-7558 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + rsvg-base.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + rsvg-cairo-draw.c | 15 +++++++++++---- + rsvg-cairo-render.c | 1 + + rsvg-filter.c | 9 +++++++-- + rsvg-private.h | 5 +++++ + 5 files changed, 79 insertions(+), 6 deletions(-) + +Index: librsvg-2.40.10/rsvg-base.c +=================================================================== +--- librsvg-2.40.10.orig/rsvg-base.c ++++ librsvg-2.40.10/rsvg-base.c +@@ -1236,6 +1236,8 @@ rsvg_drawing_ctx_free (RsvgDrawingCtx * + g_slist_free (handle->drawsub_stack); + + g_slist_free (handle->ptrs); ++ g_warn_if_fail (handle->acquired_nodes == NULL); ++ g_slist_free (handle->acquired_nodes); + + if (handle->base_uri) + g_free (handle->base_uri); +@@ -2018,6 +2020,59 @@ rsvg_push_discrete_layer (RsvgDrawingCtx + ctx->render->push_discrete_layer (ctx); + } + ++/* ++ * rsvg_acquire_node: ++ * @ctx: The drawing context in use ++ * @url: The IRI to lookup ++ * ++ * Use this function when looking up urls to other nodes. This ++ * function does proper recursion checking and thereby avoids ++ * infinite loops. ++ * ++ * Nodes acquired by this function must be released using ++ * rsvg_release_node() in reverse acquiring order. ++ * ++ * Returns: The node referenced by @url or %NULL if the @url ++ * does not reference a node. ++ */ ++RsvgNode * ++rsvg_acquire_node (RsvgDrawingCtx * ctx, const char *url) ++{ ++ RsvgNode *node; ++ ++ node = rsvg_defs_lookup (ctx->defs, url); ++ if (node == NULL) ++ return NULL; ++ ++ if (g_slist_find (ctx->acquired_nodes, node)) ++ return NULL; ++ ++ ctx->acquired_nodes = g_slist_prepend (ctx->acquired_nodes, node); ++ ++ return node; ++} ++ ++/* ++ * rsvg_release_node: ++ * @ctx: The drawing context the node was acquired from ++ * @node: Node to release ++ * ++ * Releases a node previously acquired via rsvg_acquire_node(). ++ * ++ * if @node is %NULL, this function does nothing. ++ */ ++void ++rsvg_release_node (RsvgDrawingCtx * ctx, RsvgNode *node) ++{ ++ if (node == NULL) ++ return; ++ ++ g_return_if_fail (ctx->acquired_nodes != NULL); ++ g_return_if_fail (ctx->acquired_nodes->data == node); ++ ++ ctx->acquired_nodes = g_slist_remove (ctx->acquired_nodes, node); ++} ++ + void + rsvg_render_path (RsvgDrawingCtx * ctx, const cairo_path_t *path) + { +Index: librsvg-2.40.10/rsvg-cairo-draw.c +=================================================================== +--- librsvg-2.40.10.orig/rsvg-cairo-draw.c ++++ librsvg-2.40.10/rsvg-cairo-draw.c +@@ -721,7 +721,7 @@ rsvg_cairo_push_render_stack (RsvgDrawin + + if (rsvg_current_state (ctx)->clip_path) { + RsvgNode *node; +- node = rsvg_defs_lookup (ctx->defs, rsvg_current_state (ctx)->clip_path); ++ node = rsvg_acquire_node (ctx, rsvg_current_state (ctx)->clip_path); + if (node && RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_CLIP_PATH) { + RsvgClipPath *clip_path = (RsvgClipPath *) node; + +@@ -739,6 +739,8 @@ rsvg_cairo_push_render_stack (RsvgDrawin + } + + } ++ ++ rsvg_release_node (ctx, node); + } + + if (state->opacity == 0xFF +@@ -798,10 +800,12 @@ rsvg_cairo_pop_render_stack (RsvgDrawing + + if (rsvg_current_state (ctx)->clip_path) { + RsvgNode *node; +- node = rsvg_defs_lookup (ctx->defs, rsvg_current_state (ctx)->clip_path); ++ node = rsvg_acquire_node (ctx, rsvg_current_state (ctx)->clip_path); + if (node && RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_CLIP_PATH + && ((RsvgClipPath *) node)->units == objectBoundingBox) + lateclip = (RsvgClipPath *) node; ++ else ++ rsvg_release_node (ctx, node); + } + + if (state->opacity == 0xFF +@@ -831,17 +835,20 @@ rsvg_cairo_pop_render_stack (RsvgDrawing + nest ? 0 : render->offset_x, + nest ? 0 : render->offset_y); + +- if (lateclip) ++ if (lateclip) { + rsvg_cairo_clip (ctx, lateclip, &render->bbox); ++ rsvg_release_node (ctx, (RsvgNode *) lateclip); ++ } + + cairo_set_operator (render->cr, state->comp_op); + + if (state->mask) { + RsvgNode *mask; + +- mask = rsvg_defs_lookup (ctx->defs, state->mask); ++ mask = rsvg_acquire_node (ctx, state->mask); + if (mask && RSVG_NODE_TYPE (mask) == RSVG_NODE_TYPE_MASK) + rsvg_cairo_generate_mask (render->cr, (RsvgMask *) mask, ctx, &render->bbox); ++ rsvg_release_node (ctx, mask); + } else if (state->opacity != 0xFF) + cairo_paint_with_alpha (render->cr, (double) state->opacity / 255.0); + else +Index: librsvg-2.40.10/rsvg-cairo-render.c +=================================================================== +--- librsvg-2.40.10.orig/rsvg-cairo-render.c ++++ librsvg-2.40.10/rsvg-cairo-render.c +@@ -155,6 +155,7 @@ rsvg_cairo_new_drawing_ctx (cairo_t * cr + draw->pango_context = NULL; + draw->drawsub_stack = NULL; + draw->ptrs = NULL; ++ draw->acquired_nodes = NULL; + + rsvg_state_push (draw); + state = rsvg_current_state (draw); +Index: librsvg-2.40.10/rsvg-filter.c +=================================================================== +--- librsvg-2.40.10.orig/rsvg-filter.c ++++ librsvg-2.40.10/rsvg-filter.c +@@ -3921,6 +3921,7 @@ rsvg_filter_primitive_image_render_in (R + RsvgDrawingCtx *ctx; + RsvgFilterPrimitiveImage *upself; + RsvgNode *drawable; ++ cairo_surface_t *result; + + ctx = context->ctx; + +@@ -3929,13 +3930,17 @@ rsvg_filter_primitive_image_render_in (R + if (!upself->href) + return NULL; + +- drawable = rsvg_defs_lookup (ctx->defs, upself->href->str); ++ drawable = rsvg_acquire_node (ctx, upself->href->str); + if (!drawable) + return NULL; + + rsvg_current_state (ctx)->affine = context->paffine; + +- return rsvg_get_surface_of_node (ctx, drawable, context->width, context->height); ++ result = rsvg_get_surface_of_node (ctx, drawable, context->width, context->height); ++ ++ rsvg_release_node (ctx, drawable); ++ ++ return result; + } + + static cairo_surface_t * +Index: librsvg-2.40.10/rsvg-private.h +=================================================================== +--- librsvg-2.40.10.orig/rsvg-private.h ++++ librsvg-2.40.10/rsvg-private.h +@@ -200,6 +200,7 @@ struct RsvgDrawingCtx { + GSList *vb_stack; + GSList *drawsub_stack; + GSList *ptrs; ++ GSList *acquired_nodes; + }; + + /*Abstract base class for context for our backends (one as yet)*/ +@@ -360,6 +361,10 @@ void rsvg_pop_discrete_layer (RsvgDra + G_GNUC_INTERNAL + void rsvg_push_discrete_layer (RsvgDrawingCtx * ctx); + G_GNUC_INTERNAL ++RsvgNode *rsvg_acquire_node (RsvgDrawingCtx * ctx, const char *url); ++G_GNUC_INTERNAL ++void rsvg_release_node (RsvgDrawingCtx * ctx, RsvgNode *node); ++G_GNUC_INTERNAL + void rsvg_render_path (RsvgDrawingCtx * ctx, const cairo_path_t *path); + G_GNUC_INTERNAL + void rsvg_render_surface (RsvgDrawingCtx * ctx, cairo_surface_t *surface, |