Bug#966028: buster-pu: package librsvg/2.44.10-2.1+deb10u1
On 22/07/2020 13:19, Emilio Pozuelo Monfort wrote:
> So I have gone with the minimal backport to 2.44.10 instead (which I've
> also tested) and it's already uploaded. debdiff attached.
Attached for real now.
Emilio
diff -Nru librsvg-2.44.10/debian/changelog librsvg-2.44.10/debian/changelog
--- librsvg-2.44.10/debian/changelog 2019-04-25 21:55:18.000000000 +0200
+++ librsvg-2.44.10/debian/changelog 2020-07-22 13:11:57.000000000 +0200
@@ -1,3 +1,9 @@
+librsvg (2.44.10-2.1+deb10u1) buster; urgency=medium
+
+ * CVE-2019-20446: DoS via billion laughs attack.
+
+ -- Emilio Pozuelo Monfort <pochu@debian.org> Wed, 22 Jul 2020 13:11:57 +0200
+
librsvg (2.44.10-2.1) unstable; urgency=high
* Non-maintainer upload.
diff -Nru librsvg-2.44.10/debian/patches/0001-limits.rs-New-file-move-the-constant-for-maximum-ins.patch librsvg-2.44.10/debian/patches/0001-limits.rs-New-file-move-the-constant-for-maximum-ins.patch
--- librsvg-2.44.10/debian/patches/0001-limits.rs-New-file-move-the-constant-for-maximum-ins.patch 1970-01-01 01:00:00.000000000 +0100
+++ librsvg-2.44.10/debian/patches/0001-limits.rs-New-file-move-the-constant-for-maximum-ins.patch 2020-07-11 20:11:58.000000000 +0200
@@ -0,0 +1,79 @@
+From c5738c7716f66e66ba23aa169e79eb478b7804c5 Mon Sep 17 00:00:00 2001
+From: Federico Mena Quintero <federico@gnome.org>
+Date: Thu, 10 Oct 2019 15:16:19 -0500
+Subject: [PATCH 1/5] limits.rs - New file; move the constant for maximum
+ instanced nodes here
+
+---
+ Makefile.am | 1 +
+ rsvg_internals/src/drawing_ctx.rs | 3 ++-
+ rsvg_internals/src/lib.rs | 1 +
+ rsvg_internals/src/limits.rs | 11 +++++++++++
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+ create mode 100644 rsvg_internals/src/limits.rs
+
+diff --git a/Makefile.am b/Makefile.am
+index e075c958..bb181dc2 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -81,6 +81,7 @@ RUST_SRC = \
+ rsvg_internals/src/iri.rs \
+ rsvg_internals/src/length.rs \
+ rsvg_internals/src/lib.rs \
++ rsvg_internals/src/limits.rs \
+ rsvg_internals/src/log.rs \
+ rsvg_internals/src/link.rs \
+ rsvg_internals/src/load.rs \
+diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
+index 9bf9d295..c9c2d169 100644
+--- a/rsvg_internals/src/drawing_ctx.rs
++++ b/rsvg_internals/src/drawing_ctx.rs
+@@ -19,6 +19,7 @@ use error::RenderingError;
+ use filters;
+ use float_eq_cairo::ApproxEqCairo;
+ use length::Dasharray;
++use limits;
+ use mask::NodeMask;
+ use node::{CascadedValues, NodeType, RsvgNode};
+ use paint_server::{self, PaintServer};
+@@ -863,7 +864,7 @@ impl<'a> DrawingCtx<'a> {
+ }
+
+ fn check_limits(&self) -> Result<(), RenderingError> {
+- if self.num_elements_rendered_through_use > 500_000 {
++ if self.num_elements_rendered_through_use > limits::MAX_REFERENCED_ELEMENTS {
+ Err(RenderingError::InstancingLimit)
+ } else {
+ Ok(())
+diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
+index 1d36d394..99704df4 100644
+--- a/rsvg_internals/src/lib.rs
++++ b/rsvg_internals/src/lib.rs
+@@ -113,6 +113,7 @@ mod handle;
+ mod image;
+ mod iri;
+ mod length;
++mod limits;
+ mod link;
+ mod load;
+ mod marker;
+diff --git a/rsvg_internals/src/limits.rs b/rsvg_internals/src/limits.rs
+new file mode 100644
+index 00000000..f5d58d95
+--- /dev/null
++++ b/rsvg_internals/src/limits.rs
+@@ -0,0 +1,11 @@
++/// This is a mitigation for the security-related bug
++/// https://gitlab.gnome.org/GNOME/librsvg/issues/323 - imagine
++/// the XML [billion laughs attack], but done by creating deeply
++/// nested groups of `<use>` elements. The first one references
++/// the second one ten times, the second one references the third
++/// one ten times, and so on. In the file given, this causes
++/// 10^17 objects to be rendered. While this does not exhaust
++/// memory, it would take a really long time.
++///
++/// [billion laughs attack]: https://bitbucket.org/tiran/defusedxml
++pub const MAX_REFERENCED_ELEMENTS: usize = 500_000;
+--
+2.20.1
+
diff -Nru librsvg-2.44.10/debian/patches/0002-Rename-num_elements_rendered_through_use-to-num_elem.patch librsvg-2.44.10/debian/patches/0002-Rename-num_elements_rendered_through_use-to-num_elem.patch
--- librsvg-2.44.10/debian/patches/0002-Rename-num_elements_rendered_through_use-to-num_elem.patch 1970-01-01 01:00:00.000000000 +0100
+++ librsvg-2.44.10/debian/patches/0002-Rename-num_elements_rendered_through_use-to-num_elem.patch 2020-07-11 20:11:58.000000000 +0200
@@ -0,0 +1,66 @@
+From 1b63d474943e8f1fe77757ee87f2d39502e32fda Mon Sep 17 00:00:00 2001
+From: Federico Mena Quintero <federico@gnome.org>
+Date: Thu, 10 Oct 2019 15:26:14 -0500
+Subject: [PATCH 2/5] Rename num_elements_rendered_through_use to
+ num_elements_acquired
+
+We'll change this to be the number of elements ever acquired through
+DrawingCtx.acquire_node(), instead of just those being instanced
+through the <use> element. It turns out one can create a pathological
+SVG file that causes an exponential number of elements to be rendered,
+without using <use>.
+---
+ rsvg_internals/src/drawing_ctx.rs | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
+index c9c2d169..0d0e401b 100644
+--- a/rsvg_internals/src/drawing_ctx.rs
++++ b/rsvg_internals/src/drawing_ctx.rs
+@@ -101,17 +101,9 @@ pub struct DrawingCtx<'a> {
+ dpi_x: f64,
+ dpi_y: f64,
+
+- /// This is a mitigation for the security-related bug
+- /// https://gitlab.gnome.org/GNOME/librsvg/issues/323 - imagine
+- /// the XML [billion laughs attack], but done by creating deeply
+- /// nested groups of `<use>` elements. The first one references
+- /// the second one ten times, the second one references the third
+- /// one ten times, and so on. In the file given, this causes
+- /// 10^17 objects to be rendered. While this does not exhaust
+- /// memory, it would take a really long time.
+- ///
+- /// [billion laughs attack]: https://bitbucket.org/tiran/defusedxml
+- num_elements_rendered_through_use: usize,
++ // This is a mitigation for SVG files that try to instance a huge number of
++ // elements via <use>, recursive patterns, etc. See limits.rs for details.
++ num_elements_acquired: usize,
+
+ cr_stack: Vec<cairo::Context>,
+ cr: cairo::Context,
+@@ -170,7 +162,7 @@ impl<'a> DrawingCtx<'a> {
+ rect,
+ dpi_x,
+ dpi_y,
+- num_elements_rendered_through_use: 0,
++ num_elements_acquired: 0,
+ cr_stack: Vec::new(),
+ cr: cr.clone(),
+ initial_cr: cr.clone(),
+@@ -860,11 +852,11 @@ impl<'a> DrawingCtx<'a> {
+ }
+
+ pub fn increase_num_elements_rendered_through_use(&mut self, n: usize) {
+- self.num_elements_rendered_through_use += n;
++ self.num_elements_acquired += n;
+ }
+
+ fn check_limits(&self) -> Result<(), RenderingError> {
+- if self.num_elements_rendered_through_use > limits::MAX_REFERENCED_ELEMENTS {
++ if self.num_elements_acquired > limits::MAX_REFERENCED_ELEMENTS {
+ Err(RenderingError::InstancingLimit)
+ } else {
+ Ok(())
+--
+2.20.1
+
diff -Nru librsvg-2.44.10/debian/patches/0003-Keep-track-of-the-number-of-referenced-nodes.patch librsvg-2.44.10/debian/patches/0003-Keep-track-of-the-number-of-referenced-nodes.patch
--- librsvg-2.44.10/debian/patches/0003-Keep-track-of-the-number-of-referenced-nodes.patch 1970-01-01 01:00:00.000000000 +0100
+++ librsvg-2.44.10/debian/patches/0003-Keep-track-of-the-number-of-referenced-nodes.patch 2020-07-11 20:11:58.000000000 +0200
@@ -0,0 +1,75 @@
+From d8e265b3a293a650399a1d4eb85d749596c10055 Mon Sep 17 00:00:00 2001
+From: Federico Mena Quintero <federico@gnome.org>
+Date: Wed, 26 Feb 2020 17:31:02 -0600
+Subject: [PATCH 3/5] Keep track of the number of referenced nodes
+
+---
+ rsvg_internals/src/drawing_ctx.rs | 30 ++++++++++++++++++++++--------
+ rsvg_internals/src/error.rs | 1 +
+ 2 files changed, 23 insertions(+), 8 deletions(-)
+
+diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
+index 0d0e401b..6dfadc8e 100644
+--- a/rsvg_internals/src/drawing_ctx.rs
++++ b/rsvg_internals/src/drawing_ctx.rs
+@@ -275,15 +275,29 @@ impl<'a> DrawingCtx<'a> {
+ // acquire it again. If you acquire a node "#foo" and don't release it before
+ // trying to acquire "foo" again, you will obtain a %NULL the second time.
+ pub fn get_acquired_node(&mut self, url: &str) -> Option<AcquiredNode> {
+- if let Some(node) = self.defs.borrow_mut().lookup(url) {
+- if !self.acquired_nodes_contains(node) {
+- self.acquired_nodes.borrow_mut().push(node.clone());
+- let acq = AcquiredNode(self.acquired_nodes.clone(), node.clone());
+- return Some(acq);
+- }
++ self.num_elements_acquired += 1;
++
++ if self.num_elements_acquired > limits::MAX_REFERENCED_ELEMENTS {
++ return None;
++ }
++
++ let mut defs_mut = self.defs.borrow_mut();
++
++ if let Some(node) = defs_mut.lookup(url) {
++ self.acquire_node_ref(node)
++ } else {
++ None
+ }
++ }
+
+- None
++ pub fn acquire_node_ref(&self, node: &RsvgNode) -> Option<AcquiredNode> {
++ if !self.acquired_nodes_contains(node) {
++ self.acquired_nodes.borrow_mut().push(node.clone());
++ let acq = AcquiredNode(self.acquired_nodes.clone(), node.clone());
++ Some(acq)
++ } else {
++ None
++ }
+ }
+
+ fn acquired_nodes_contains(&self, node: &RsvgNode) -> bool {
+@@ -857,7 +871,7 @@ impl<'a> DrawingCtx<'a> {
+
+ fn check_limits(&self) -> Result<(), RenderingError> {
+ if self.num_elements_acquired > limits::MAX_REFERENCED_ELEMENTS {
+- Err(RenderingError::InstancingLimit)
++ Err(RenderingError::MaxReferencesExceeded)
+ } else {
+ Ok(())
+ }
+diff --git a/rsvg_internals/src/error.rs b/rsvg_internals/src/error.rs
+index df0d9b9d..6d853505 100644
+--- a/rsvg_internals/src/error.rs
++++ b/rsvg_internals/src/error.rs
+@@ -91,6 +91,7 @@ pub enum RenderingError {
+ Cairo(cairo::Status),
+ CircularReference,
+ InstancingLimit,
++ MaxReferencesExceeded,
+ }
+
+ impl From<cairo::Status> for RenderingError {
+--
+2.20.1
+
diff -Nru librsvg-2.44.10/debian/patches/0004-NodeUse-fix-infinite-loops-due-to-recursive-referenc.patch librsvg-2.44.10/debian/patches/0004-NodeUse-fix-infinite-loops-due-to-recursive-referenc.patch
--- librsvg-2.44.10/debian/patches/0004-NodeUse-fix-infinite-loops-due-to-recursive-referenc.patch 1970-01-01 01:00:00.000000000 +0100
+++ librsvg-2.44.10/debian/patches/0004-NodeUse-fix-infinite-loops-due-to-recursive-referenc.patch 2020-07-11 20:11:58.000000000 +0200
@@ -0,0 +1,331 @@
+From 9f3432763bfe42f91415abb45bdcc89e0c8a355c Mon Sep 17 00:00:00 2001
+From: Federico Mena Quintero <federico@gnome.org>
+Date: Wed, 26 Feb 2020 17:46:05 -0600
+Subject: [PATCH 4/5] NodeUse: fix infinite loops due to recursive references
+ of "use" elements
+
+---
+ rsvg_internals/src/drawing_ctx.rs | 4 -
+ rsvg_internals/src/structure.rs | 19 ++-
+ tests/errors.c | 42 +++++-
+ .../errors/308-doubly-recursive-use.svg | 13 ++
+ tests/fixtures/errors/308-recursive-use.svg | 9 ++
+ tests/fixtures/errors/308-use-self-ref.svg | 7 +
+ .../errors/515-pattern-billion-laughs.svg | 130 ++++++++++++++++++
+ 7 files changed, 207 insertions(+), 17 deletions(-)
+ create mode 100644 tests/fixtures/errors/308-doubly-recursive-use.svg
+ create mode 100644 tests/fixtures/errors/308-recursive-use.svg
+ create mode 100644 tests/fixtures/errors/308-use-self-ref.svg
+ create mode 100644 tests/fixtures/errors/515-pattern-billion-laughs.svg
+
+diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
+index 6dfadc8e..890b1ac2 100644
+--- a/rsvg_internals/src/drawing_ctx.rs
++++ b/rsvg_internals/src/drawing_ctx.rs
+@@ -865,10 +865,6 @@ impl<'a> DrawingCtx<'a> {
+ }
+ }
+
+- pub fn increase_num_elements_rendered_through_use(&mut self, n: usize) {
+- self.num_elements_acquired += n;
+- }
+-
+ fn check_limits(&self) -> Result<(), RenderingError> {
+ if self.num_elements_acquired > limits::MAX_REFERENCED_ELEMENTS {
+ Err(RenderingError::MaxReferencesExceeded)
+diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
+index f384413e..b7e53ce2 100644
+--- a/rsvg_internals/src/structure.rs
++++ b/rsvg_internals/src/structure.rs
+@@ -297,6 +297,18 @@ impl NodeTrait for NodeUse {
+
+ let uri = link.as_ref().unwrap();
+
++ // <use> is an element that is used directly, unlike
++ // <pattern>, which is used through a fill="url(#...)"
++ // reference. However, <use> will always reference another
++ // element, potentially itself or an ancestor of itself (or
++ // another <use> which references the first one, etc.). So,
++ // we acquire the <use> element itself so that circular
++ // references can be caught.
++ let self_acquired = draw_ctx.acquire_node_ref(node);
++ if self_acquired.is_none() {
++ return Err(RenderingError::CircularReference);
++ }
++
+ let child = if let Some(acquired) = draw_ctx.get_acquired_node(uri) {
+ // Here we clone the acquired child, so that we can drop the AcquiredNode as
+ // early as possible. This is so that the child's drawing method will be able
+@@ -311,13 +323,6 @@ impl NodeTrait for NodeUse {
+ return Ok(());
+ };
+
+- if Node::is_ancestor(child.clone(), node.clone()) {
+- // or, if we're <use>'ing ourselves
+- return Err(RenderingError::CircularReference);
+- }
+-
+- draw_ctx.increase_num_elements_rendered_through_use(1);
+-
+ let params = draw_ctx.get_view_params();
+
+ let nx = self.x.get().normalize(values, ¶ms);
+diff --git a/tests/errors.c b/tests/errors.c
+index bdf6db7b..85663004 100644
+--- a/tests/errors.c
++++ b/tests/errors.c
+@@ -24,9 +24,10 @@ get_test_filename (const char *basename) {
+ }
+
+ static void
+-test_non_svg_element (void)
++test_loading_error (gconstpointer data)
+ {
+- char *filename = get_test_filename ("335-non-svg-element.svg");
++ const char *basename = data;
++ char *filename = get_test_filename (basename);
+ RsvgHandle *handle;
+ GError *error = NULL;
+
+@@ -35,12 +36,15 @@ test_non_svg_element (void)
+
+ g_assert (handle == NULL);
+ g_assert (g_error_matches (error, RSVG_ERROR, RSVG_ERROR_FAILED));
++
++ g_error_free (error);
+ }
+
+ static void
+-test_instancing_limit (void)
++test_instancing_limit (gconstpointer data)
+ {
+- char *filename = get_test_filename ("323-nested-use.svg");
++ const char *basename = data;
++ char *filename = get_test_filename (basename);
+ RsvgHandle *handle;
+ GError *error = NULL;
+ cairo_surface_t *surf;
+@@ -64,8 +68,34 @@ main (int argc, char **argv)
+ {
+ g_test_init (&argc, &argv, NULL);
+
+- g_test_add_func ("/errors/non_svg_element", test_non_svg_element);
+- g_test_add_func ("/errors/instancing_limit", test_instancing_limit);
++ g_test_add_data_func_full ("/errors/non_svg_element",
++ "335-non-svg-element.svg",
++ test_loading_error,
++ NULL);
++
++ g_test_add_data_func_full ("/errors/instancing_limit/323-nested-use.svg",
++ "323-nested-use.svg",
++ test_instancing_limit,
++ NULL);
++
++ g_test_add_data_func_full ("/errors/instancing_limit/515-pattern-billion-laughs.svg",
++ "515-pattern-billion-laughs.svg",
++ test_instancing_limit,
++ NULL);
++
++ g_test_add_data_func_full ("/errors/instancing_limit/308-use-self-ref.svg",
++ "308-use-self-ref.svg",
++ test_instancing_limit,
++ NULL);
++ g_test_add_data_func_full ("/errors/instancing_limit/308-recursive-use.svg",
++ "308-recursive-use.svg",
++ test_instancing_limit,
++ NULL);
++ g_test_add_data_func_full ("/errors/instancing_limit/308-doubly-recursive-use.svg",
++ "308-doubly-recursive-use.svg",
++ test_instancing_limit,
++ NULL);
++
+
+ return g_test_run ();
+ }
+diff --git a/tests/fixtures/errors/308-doubly-recursive-use.svg b/tests/fixtures/errors/308-doubly-recursive-use.svg
+new file mode 100644
+index 00000000..9b248a6f
+--- /dev/null
++++ b/tests/fixtures/errors/308-doubly-recursive-use.svg
+@@ -0,0 +1,13 @@
++<svg>
++ <defs>
++ <g id="one">
++ <use xlink:href="#two"/>
++ </g>
++
++ <g id="two">
++ <use xlink:href="#one"/>
++ </g>
++ </defs>
++
++ <use xlink:href="#one"/>
++</svg>
+diff --git a/tests/fixtures/errors/308-recursive-use.svg b/tests/fixtures/errors/308-recursive-use.svg
+new file mode 100644
+index 00000000..f5d00bf2
+--- /dev/null
++++ b/tests/fixtures/errors/308-recursive-use.svg
+@@ -0,0 +1,9 @@
++<svg>
++ <defs>
++ <g id="one">
++ <use xlink:href="#one"/>
++ </g>
++ </defs>
++
++ <use xlink:href="#one"/>
++</svg>
+diff --git a/tests/fixtures/errors/308-use-self-ref.svg b/tests/fixtures/errors/308-use-self-ref.svg
+new file mode 100644
+index 00000000..dbf14c54
+--- /dev/null
++++ b/tests/fixtures/errors/308-use-self-ref.svg
+@@ -0,0 +1,7 @@
++<svg>
++ <defs>
++ <use id="one" xlink:href="#one"/>
++ </defs>
++
++ <use xlink:href="#one"/>
++</svg>
+diff --git a/tests/fixtures/errors/515-pattern-billion-laughs.svg b/tests/fixtures/errors/515-pattern-billion-laughs.svg
+new file mode 100644
+index 00000000..1cb6cbe8
+--- /dev/null
++++ b/tests/fixtures/errors/515-pattern-billion-laughs.svg
+@@ -0,0 +1,130 @@
++<?xml version="1.0" standalone="no"?>
++<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
++ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
++<svg width="40cm" height="20cm" viewBox="0 0 800 400" version="1.1"
++ xmlns="http://www.w3.org/2000/svg">
++ <defs>
++ <pattern id="z" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(10,10)">
++ <rect x="0" y="0" width="20" height="20" fill="url(#i)" stroke="yellow"/>
++ </pattern>
++
++ <pattern id="i" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
++ <rect x="0" y="0" width="20" height="20" fill="url(#h)" stroke="green" />
++ <rect x="1" y="1" width="20" height="20" fill="url(#h)" stroke="brown" />
++ <rect x="2" y="2" width="20" height="20" fill="url(#h)" stroke="pink" />
++ <rect x="3" y="3" width="20" height="20" fill="url(#h)" stroke="grey" />
++ <rect x="4" y="3" width="20" height="20" fill="url(#h)" stroke="cyan" />
++ <rect x="5" y="3" width="20" height="20" fill="url(#h)" stroke="green" />
++ <rect x="6" y="3" width="20" height="20" fill="url(#h)" stroke="brown" />
++ <rect x="7" y="3" width="20" height="20" fill="url(#h)" stroke="pink" />
++ <rect x="8" y="3" width="20" height="20" fill="url(#h)" stroke="grey" />
++ <rect x="9" y="3" width="20" height="20" fill="url(#h)" stroke="cyan" />
++ </pattern>
++
++ <pattern id="h" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
++ <rect x="0" y="0" width="20" height="20" fill="url(#g)" stroke="green" />
++ <rect x="1" y="1" width="20" height="20" fill="url(#g)" stroke="brown" />
++ <rect x="2" y="2" width="20" height="20" fill="url(#g)" stroke="pink" />
++ <rect x="3" y="3" width="20" height="20" fill="url(#g)" stroke="grey" />
++ <rect x="4" y="3" width="20" height="20" fill="url(#g)" stroke="cyan" />
++ <rect x="5" y="3" width="20" height="20" fill="url(#g)" stroke="green" />
++ <rect x="6" y="3" width="20" height="20" fill="url(#g)" stroke="brown" />
++ <rect x="7" y="3" width="20" height="20" fill="url(#g)" stroke="pink" />
++ <rect x="8" y="3" width="20" height="20" fill="url(#g)" stroke="grey" />
++ <rect x="9" y="3" width="20" height="20" fill="url(#g)" stroke="cyan" />
++ </pattern>
++
++ <pattern id="g" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
++ <rect x="0" y="0" width="20" height="20" fill="url(#f)" stroke="green" />
++ <rect x="1" y="1" width="20" height="20" fill="url(#f)" stroke="brown" />
++ <rect x="2" y="2" width="20" height="20" fill="url(#f)" stroke="pink" />
++ <rect x="3" y="3" width="20" height="20" fill="url(#f)" stroke="grey" />
++ <rect x="4" y="3" width="20" height="20" fill="url(#f)" stroke="cyan" />
++ <rect x="5" y="3" width="20" height="20" fill="url(#f)" stroke="green" />
++ <rect x="6" y="3" width="20" height="20" fill="url(#f)" stroke="brown" />
++ <rect x="7" y="3" width="20" height="20" fill="url(#f)" stroke="pink" />
++ <rect x="8" y="3" width="20" height="20" fill="url(#f)" stroke="grey" />
++ <rect x="9" y="3" width="20" height="20" fill="url(#f)" stroke="cyan" />
++ </pattern>
++
++ <pattern id="f" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
++ <rect x="0" y="0" width="20" height="20" fill="url(#e)" stroke="green" />
++ <rect x="1" y="1" width="20" height="20" fill="url(#e)" stroke="brown" />
++ <rect x="2" y="2" width="20" height="20" fill="url(#e)" stroke="pink" />
++ <rect x="3" y="3" width="20" height="20" fill="url(#e)" stroke="grey" />
++ <rect x="4" y="3" width="20" height="20" fill="url(#e)" stroke="cyan" />
++ <rect x="5" y="3" width="20" height="20" fill="url(#e)" stroke="green" />
++ <rect x="6" y="3" width="20" height="20" fill="url(#e)" stroke="brown" />
++ <rect x="7" y="3" width="20" height="20" fill="url(#e)" stroke="pink" />
++ <rect x="8" y="3" width="20" height="20" fill="url(#e)" stroke="grey" />
++ <rect x="9" y="3" width="20" height="20" fill="url(#e)" stroke="cyan" />
++ </pattern>
++
++ <pattern id="e" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
++ <rect x="0" y="0" width="20" height="20" fill="url(#d)" stroke="green" />
++ <rect x="1" y="1" width="20" height="20" fill="url(#d)" stroke="brown" />
++ <rect x="2" y="2" width="20" height="20" fill="url(#d)" stroke="pink" />
++ <rect x="3" y="3" width="20" height="20" fill="url(#d)" stroke="grey" />
++ <rect x="4" y="3" width="20" height="20" fill="url(#d)" stroke="cyan" />
++ <rect x="5" y="3" width="20" height="20" fill="url(#d)" stroke="green" />
++ <rect x="6" y="3" width="20" height="20" fill="url(#d)" stroke="brown" />
++ <rect x="7" y="3" width="20" height="20" fill="url(#d)" stroke="pink" />
++ <rect x="8" y="3" width="20" height="20" fill="url(#d)" stroke="grey" />
++ <rect x="9" y="3" width="20" height="20" fill="url(#d)" stroke="cyan" />
++ </pattern>
++
++ <pattern id="d" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
++ <rect x="0" y="0" width="20" height="20" fill="url(#c)" stroke="green" />
++ <rect x="1" y="1" width="20" height="20" fill="url(#c)" stroke="brown" />
++ <rect x="2" y="2" width="20" height="20" fill="url(#c)" stroke="pink" />
++ <rect x="3" y="3" width="20" height="20" fill="url(#c)" stroke="grey" />
++ <rect x="4" y="3" width="20" height="20" fill="url(#c)" stroke="cyan" />
++ <rect x="5" y="3" width="20" height="20" fill="url(#c)" stroke="green" />
++ <rect x="6" y="3" width="20" height="20" fill="url(#c)" stroke="brown" />
++ <rect x="7" y="3" width="20" height="20" fill="url(#c)" stroke="pink" />
++ <rect x="8" y="3" width="20" height="20" fill="url(#c)" stroke="grey" />
++ <rect x="9" y="3" width="20" height="20" fill="url(#c)" stroke="cyan" />
++ </pattern>
++ <pattern id="c" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
++ <rect x="0" y="0" width="20" height="20" fill="url(#b)" stroke="green" />
++ <rect x="1" y="1" width="20" height="20" fill="url(#b)" stroke="brown" />
++ <rect x="2" y="2" width="20" height="20" fill="url(#b)" stroke="pink" />
++ <rect x="3" y="3" width="20" height="20" fill="url(#b)" stroke="grey" />
++ <rect x="4" y="3" width="20" height="20" fill="url(#b)" stroke="cyan" />
++ <rect x="5" y="3" width="20" height="20" fill="url(#b)" stroke="green" />
++ <rect x="6" y="3" width="20" height="20" fill="url(#b)" stroke="brown" />
++ <rect x="7" y="3" width="20" height="20" fill="url(#b)" stroke="pink" />
++ <rect x="8" y="3" width="20" height="20" fill="url(#b)" stroke="grey" />
++ <rect x="9" y="3" width="20" height="20" fill="url(#b)" stroke="cyan" />
++ </pattern>
++ <pattern id="b" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
++ <rect x="0" y="0" width="20" height="20" fill="url(#a)" stroke="green" />
++ <rect x="1" y="1" width="20" height="20" fill="url(#a)" stroke="brown" />
++ <rect x="2" y="2" width="20" height="20" fill="url(#a)" stroke="pink" />
++ <rect x="3" y="3" width="20" height="20" fill="url(#a)" stroke="grey" />
++ <rect x="4" y="3" width="20" height="20" fill="url(#a)" stroke="cyan" />
++ <rect x="5" y="3" width="20" height="20" fill="url(#a)" stroke="green" />
++ <rect x="6" y="3" width="20" height="20" fill="url(#a)" stroke="brown" />
++ <rect x="7" y="3" width="20" height="20" fill="url(#a)" stroke="pink" />
++ <rect x="8" y="3" width="20" height="20" fill="url(#a)" stroke="grey" />
++ <rect x="9" y="3" width="20" height="20" fill="url(#a)" stroke="cyan" />
++
++ </pattern>
++ <pattern id="a" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
++ <rect x="0" y="0" width="20" height="20" fill="none" stroke="green" />
++ <rect x="1" y="1" width="20" height="20" fill="none" stroke="brown" />
++ <rect x="2" y="2" width="20" height="20" fill="none" stroke="pink" />
++ <rect x="3" y="3" width="20" height="20" fill="none" stroke="grey" />
++ <rect x="4" y="3" width="20" height="20" fill="none" stroke="cyan" />
++ <rect x="5" y="3" width="20" height="20" fill="none" stroke="green" />
++ <rect x="6" y="3" width="20" height="20" fill="none" stroke="brown" />
++ <rect x="7" y="3" width="20" height="20" fill="none" stroke="pink" />
++ <rect x="8" y="3" width="20" height="20" fill="none" stroke="grey" />
++ <rect x="9" y="3" width="20" height="20" fill="none" stroke="cyan" />
++ </pattern>
++ </defs>
++
++ <ellipse fill="url(#z)" stroke="black" stroke-width="5"
++ cx="400" cy="200" rx="350" ry="150" />
++
++</svg>
+\ No newline at end of file
+--
+2.20.1
+
diff -Nru librsvg-2.44.10/debian/patches/0005-Limit-the-number-of-loaded-elements.patch librsvg-2.44.10/debian/patches/0005-Limit-the-number-of-loaded-elements.patch
--- librsvg-2.44.10/debian/patches/0005-Limit-the-number-of-loaded-elements.patch 1970-01-01 01:00:00.000000000 +0100
+++ librsvg-2.44.10/debian/patches/0005-Limit-the-number-of-loaded-elements.patch 2020-07-11 20:17:33.000000000 +0200
@@ -0,0 +1,75 @@
+From 5edea8ca9fbecbd6c36f7fd28894e49f356d8b78 Mon Sep 17 00:00:00 2001
+From: Federico Mena Quintero <federico@gnome.org>
+Date: Wed, 26 Feb 2020 19:06:56 -0600
+Subject: [PATCH 5/5] Limit the number of loaded elements
+
+---
+ librsvg/rsvg-load.c | 20 ++++++++++++++++++
+ tests/errors.c | 4 ++++
+ .../errors/515-too-many-elements.svgz | Bin 0 -> 40811 bytes
+ 3 files changed, 24 insertions(+)
+ create mode 100644 tests/fixtures/errors/515-too-many-elements.svgz
+
+diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
+index 44e1f670..ea1e2bfb 100644
+--- a/librsvg/rsvg-load.c
++++ b/librsvg/rsvg-load.c
+@@ -66,6 +66,7 @@ struct RsvgLoad {
+ */
+ RsvgSaxHandler *handler;
+ int handler_nest;
++ gsize num_loaded_elements;
+
+ GHashTable *entities; /* g_malloc'd string -> xmlEntityPtr */
+
+@@ -608,12 +609,31 @@ start_xinclude (RsvgLoad *load, RsvgPropertyBag * atts)
+
+ /* end xinclude */
+
++static gboolean
++loading_limits_exceeded (RsvgLoad *load)
++{
++ /* This is a mitigation for SVG files which create millions of elements
++ * in an attempt to exhaust memory. We don't allow loading more than
++ * this number of elements during the initial streaming load process.
++ */
++ return load->num_loaded_elements > 200000;
++}
++
+ static void
+ sax_start_element_cb (void *data, const xmlChar * name, const xmlChar ** atts)
+ {
+ RsvgPropertyBag bag;
+ RsvgLoad *load = data;
+
++ if (loading_limits_exceeded (load)) {
++ g_set_error (load->error, RSVG_ERROR, 0, "instancing limit");
++
++ xmlStopParser (load->ctxt);
++ return;
++ }
++
++ load->num_loaded_elements += 1;
++
+ bag = rsvg_property_bag_new ((const char **) atts);
+
+ if (load->handler) {
+diff --git a/tests/errors.c b/tests/errors.c
+index 85663004..52795680 100644
+--- a/tests/errors.c
++++ b/tests/errors.c
+@@ -96,6 +96,10 @@ main (int argc, char **argv)
+ test_instancing_limit,
+ NULL);
+
++ g_test_add_data_func_full ("/errors/515-too-many-elements.svgz",
++ "515-too-many-elements.svgz",
++ test_loading_error,
++ NULL);
+
+ return g_test_run ();
+ }
+
+--
+2.20.1
+
diff -Nru librsvg-2.44.10/debian/patches/series librsvg-2.44.10/debian/patches/series
--- librsvg-2.44.10/debian/patches/series 2019-04-25 21:54:21.000000000 +0200
+++ librsvg-2.44.10/debian/patches/series 2020-07-11 20:12:17.000000000 +0200
@@ -2,3 +2,8 @@
typenum-i386-ftbfs.patch
i386-rounding-errors.patch
keep-positive-radii.patch
+0001-limits.rs-New-file-move-the-constant-for-maximum-ins.patch
+0002-Rename-num_elements_rendered_through_use-to-num_elem.patch
+0003-Keep-track-of-the-number-of-referenced-nodes.patch
+0004-NodeUse-fix-infinite-loops-due-to-recursive-referenc.patch
+0005-Limit-the-number-of-loaded-elements.patch
diff -Nru librsvg-2.44.10/debian/source/include-binaries librsvg-2.44.10/debian/source/include-binaries
--- librsvg-2.44.10/debian/source/include-binaries 1970-01-01 01:00:00.000000000 +0100
+++ librsvg-2.44.10/debian/source/include-binaries 2020-07-11 20:20:12.000000000 +0200
@@ -0,0 +1 @@
+tests/fixtures/errors/515-too-many-elements.svgz
Binary files /tmp/dtBncWIUMD/librsvg-2.44.10/tests/fixtures/errors/515-too-many-elements.svgz and /tmp/pPLtG7c90L/librsvg-2.44.10/tests/fixtures/errors/515-too-many-elements.svgz differ
Reply to: