On 25/07/2020 12:04, Adam D. Barratt wrote: > Hi, > > On Wed, 2020-07-22 at 13:26 +0200, Emilio Pozuelo Monfort wrote: >> 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. > > Unfortunately it appears that this FTBFS on ppc64el and s390x, with a > segmentation fault in the tests.
I have uploaded a new revision, fixing this FTBFS and the one caused by the new rustc 1.41. debdiff attached. Cheers, Emilio
diff -Nru librsvg-2.44.10/debian/changelog librsvg-2.44.10/debian/changelog --- librsvg-2.44.10/debian/changelog 2020-07-22 13:11:57.000000000 +0200 +++ librsvg-2.44.10/debian/changelog 2020-09-20 10:48:42.000000000 +0200 @@ -1,3 +1,12 @@ +librsvg (2.44.10-2.1+deb10u2) buster; urgency=medium + + * nalgebra-borrow-mutable-immutable.patch: fix build with rustc 1.41. + * Don-t-drop-nodes-recursively-to-avoid-stack-over.patch: fix stack + exhaustion due to recursion when freeing nodes, which caused FTBFS + on ppc64el and s390x with the newly introduced tests for CVE-2019-20446. + + -- Emilio Pozuelo Monfort <po...@debian.org> Sun, 20 Sep 2020 10:48:42 +0200 + librsvg (2.44.10-2.1+deb10u1) buster; urgency=medium * CVE-2019-20446: DoS via billion laughs attack. diff -Nru librsvg-2.44.10/debian/patches/Don-t-drop-nodes-recursively-to-avoid-stack-over.patch librsvg-2.44.10/debian/patches/Don-t-drop-nodes-recursively-to-avoid-stack-over.patch --- librsvg-2.44.10/debian/patches/Don-t-drop-nodes-recursively-to-avoid-stack-over.patch 1970-01-01 01:00:00.000000000 +0100 +++ librsvg-2.44.10/debian/patches/Don-t-drop-nodes-recursively-to-avoid-stack-over.patch 2020-09-20 10:46:33.000000000 +0200 @@ -0,0 +1,96 @@ +From 1235c2de5bbeb16deb48013505c6b2a767915c03 Mon Sep 17 00:00:00 2001 +From: Federico Mena Quintero <feder...@gnome.org> +Date: Fri, 14 Dec 2018 17:00:08 -0600 +Subject: [PATCH] (#393): Don't drop nodes recursively to avoid stack overflow + +We borrow a dropping technique from Kuchiki, to avoid deep recursion +when there are thousands of sibling nodes. + +https://gitlab.gnome.org/GNOME/librsvg/issues/393 +--- + rsvg_internals/src/node.rs | 69 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +diff --git a/rsvg_internals/src/node.rs b/rsvg_internals/src/node.rs +index 36e3df03..493ae844 100644 +--- a/rsvg_internals/src/node.rs ++++ b/rsvg_internals/src/node.rs +@@ -655,6 +655,75 @@ impl Node { + } + } + ++/// Prevent stack overflow when recursively dropping nodes ++/// ++/// Dropping nodes is recursive, since a node owns strong references ++/// to its next sibling and its first child. When there is an SVG ++/// with a flat hierarchy of a few hundred thousand elements, ++/// recursively dropping these siblings can cause stack overflow. ++/// ++/// Here, we convert recursion to an explicit heap-allocated stack of ++/// nodes that need to be dropped. This technique is borrowed from ++/// [kuchiki]'s tree implementation. ++/// ++/// [kuchiki]: https://github.com/kuchiki-rs/kuchiki/blob/master/src/tree.rs ++impl Drop for Node { ++ fn drop(&mut self) { ++ let mut stack = Vec::new(); ++ ++ if let Some(rc) = take_if_unique_strong(&self.first_child) { ++ non_recursive_drop_unique_rc(rc, &mut stack); ++ } ++ ++ if let Some(rc) = take_if_unique_strong(&self.next_sib) { ++ non_recursive_drop_unique_rc(rc, &mut stack); ++ } ++ ++ fn non_recursive_drop_unique_rc(mut rc: Rc<Node>, stack: &mut Vec<Rc<Node>>) { ++ loop { ++ if let Some(child) = take_if_unique_strong(&rc.first_child) { ++ stack.push(rc); ++ rc = child; ++ continue; ++ } ++ ++ if let Some(sibling) = take_if_unique_strong(&rc.next_sib) { ++ rc = sibling; ++ continue; ++ } ++ ++ if let Some(parent) = stack.pop() { ++ rc = parent; ++ continue; ++ } ++ ++ return; ++ } ++ } ++ } ++} ++ ++/// Return `Some` if the `NodeRef` is the only strong reference count ++/// ++/// Note that this leaves the tree in a partially inconsistent state, since ++/// the weak references to the node referenced by `r` will now point to ++/// an unlinked node. ++fn take_if_unique_strong(r: &RefCell<Option<Rc<Node>>>) -> Option<Rc<Node>> { ++ let mut r = r.borrow_mut(); ++ ++ let has_single_ref = match *r { ++ None => false, ++ Some(ref rc) if Rc::strong_count(rc) > 1 => false, ++ Some(_) => true, ++ }; ++ ++ if has_single_ref { ++ r.take() ++ } else { ++ None ++ } ++} ++ + pub fn node_ptr_to_weak(raw_parent: *const RsvgNode) -> Option<Weak<Node>> { + if raw_parent.is_null() { + None +-- +2.20.1 + diff -Nru librsvg-2.44.10/debian/patches/nalgebra-borrow-mutable-immutable.patch librsvg-2.44.10/debian/patches/nalgebra-borrow-mutable-immutable.patch --- librsvg-2.44.10/debian/patches/nalgebra-borrow-mutable-immutable.patch 1970-01-01 01:00:00.000000000 +0100 +++ librsvg-2.44.10/debian/patches/nalgebra-borrow-mutable-immutable.patch 2020-09-20 09:55:59.000000000 +0200 @@ -0,0 +1,14 @@ +Fix build with rustc 1.41 + +--- librsvg-2.44.10/vendor/nalgebra/src/base/cg.rs 2018-12-11 19:09:12.000000000 +0100 ++++ librsvg-2.44.16/vendor/nalgebra/src/base/cg.rs 2020-02-27 02:12:51.000000000 +0100 +@@ -289,7 +288,8 @@ impl<N: Scalar + Ring, D: DimName, S: St + { + for i in 0..D::dim() { + for j in 0..D::dim() - 1 { +- self[(j, i)] += shift[j] * self[(D::dim() - 1, i)]; ++ let add = shift[j] * self[(D::dim() - 1, i)]; ++ self[(j, i)] += add; + } + } + } diff -Nru librsvg-2.44.10/debian/patches/series librsvg-2.44.10/debian/patches/series --- librsvg-2.44.10/debian/patches/series 2020-07-11 20:12:17.000000000 +0200 +++ librsvg-2.44.10/debian/patches/series 2020-09-20 10:46:58.000000000 +0200 @@ -7,3 +7,5 @@ 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 +nalgebra-borrow-mutable-immutable.patch +Don-t-drop-nodes-recursively-to-avoid-stack-over.patch