aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-gnome/librsvg/librsvg/CVE-2015-7558_3.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-gnome/librsvg/librsvg/CVE-2015-7558_3.patch')
-rw-r--r--meta/recipes-gnome/librsvg/librsvg/CVE-2015-7558_3.patch223
1 files changed, 223 insertions, 0 deletions
diff --git a/meta/recipes-gnome/librsvg/librsvg/CVE-2015-7558_3.patch b/meta/recipes-gnome/librsvg/librsvg/CVE-2015-7558_3.patch
new file mode 100644
index 0000000000..dd67ab768d
--- /dev/null
+++ b/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,