Version in base suite: 2.60.0+dfsg-1 Base version: librsvg_2.60.0+dfsg-1 Target version: librsvg_2.60.0+dfsg-1+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/libr/librsvg/librsvg_2.60.0+dfsg-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/libr/librsvg/librsvg_2.60.0+dfsg-1+deb13u1.dsc changelog | 6 + patches/CVE-2026-96889.patch | 163 +++++++++++++++++++++++++++++++++++++++++++ patches/series | 1 3 files changed, 170 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpuhs2t1b2/librsvg_2.60.0+dfsg-1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpuhs2t1b2/librsvg_2.60.0+dfsg-1+deb13u1.dsc: no acceptable signature found diff -Nru librsvg-2.60.0+dfsg/debian/changelog librsvg-2.60.0+dfsg/debian/changelog --- librsvg-2.60.0+dfsg/debian/changelog 2025-03-19 12:29:39.000000000 +0000 +++ librsvg-2.60.0+dfsg/debian/changelog 2026-10-06 22:03:53.000000000 +0000 @@ -1,3 +1,9 @@ +librsvg (2.60.0+dfsg-1+deb13u1) trixie-security; urgency=medium + + * CVE-2026-96889 (Closes: #1148902) + + -- Moritz Mühlenhoff Wed, 07 Oct 2026 00:03:53 +0200 + librsvg (2.60.0+dfsg-1) unstable; urgency=medium * New upstream release diff -Nru librsvg-2.60.0+dfsg/debian/patches/CVE-2026-96889.patch librsvg-2.60.0+dfsg/debian/patches/CVE-2026-96889.patch --- librsvg-2.60.0+dfsg/debian/patches/CVE-2026-96889.patch 1970-01-01 00:00:00.000000000 +0000 +++ librsvg-2.60.0+dfsg/debian/patches/CVE-2026-96889.patch 2026-10-06 22:03:53.000000000 +0000 @@ -0,0 +1,163 @@ +From 1606574427408baca8203ef723281509a229f9e2 Mon Sep 17 00:00:00 2001 +From: Federico Mena Quintero +Date: Thu, 17 Sep 2026 16:21:32 -0600 +Subject: [PATCH] (#1241): Fix use-after-free with duplicate XML entities + +When an included XML document declares an entity with a duplicate name +as an existing one, librsvg would deallocate the old xmlEntityPtr in +XmlEntity::drop() when the duplicate entity is inserted in the hash +table. However, libxml2 still keeps pointers around to the entity +declared in the base document, and makes use of them. + +This commit makes librsvg ignore entity declarations when they come in +with the same name as an entity that has already been declared. This +is probably not 100% correct in terms of XML semantics, but I don't +recall seeing text about that in the Xinclude spec. + +Thanks to Rafael B. Dias for reporting this in detail. + +==3942== Invalid read of size 1 +==3942== at 0x5B49A40: xmlParseElementStart (parser.c:9758) +==3942== by 0x5B4E87D: xmlParseContentInternal (parser.c:9580) +==3942== by 0x5B4DF4D: xmlCtxtParseContentInternal (parser.c:11712) +==3942== by 0x5B4E151: xmlCtxtParseEntity (parser.c:11818) +==3942== by 0x5B4E367: xmlParseReference (parser.c:7226) +==3942== by 0x5B4E857: xmlParseContentInternal (parser.c:9590) +==3942== by 0x5B4EA67: xmlParseElement (parser.c:9672) +==3942== by 0x5B515B7: xmlParseDocument (parser.c:10468) +==3942== by 0x463164B: ::parse (xml2_load.rs:471) +==3942== by 0x45E0B90: ::parse_from_stream::{closure#0} (mod.rs:648) +==3942== by 0x45916BF: , rsvg::error::LoadingError>>::and_then::<(), ::parse_from_stream::{closure#0}> (library/core/src/result.rs:1493) +==3942== by 0x45E2B54: ::parse_from_stream (mod.rs:648) +==3942== by 0x45E25FF: ::build_document (mod.rs:661) +==3942== by 0x45E667B: rsvg::xml::xml_load_from_possibly_compressed_stream (mod.rs:764) +==3942== by 0x46F3DC1: ::load_from_stream (document.rs:216) +==3942== by 0x44A97FC: ::read_stream:: (api.rs:303) +==3942== Address 0x697f109 is 233 bytes inside a block of size 235 free'd +==3942== at 0x578F9BF: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) +==3942== by 0x5B3687C: xmlFreeEntity (entities.c:107) +==3942== by 0x44BAD1D: ::drop (mod.rs:97) +==3942== by 0x44B4DFA: core::ptr::drop_glue:: (library/core/src/ptr/mod.rs:825) +==3942== by 0x44ABB37: core::ptr::drop_glue::> (library/core/src/ptr/mod.rs:825) +==3942== by 0x45E1E2C: ::entity_insert (mod.rs:375) +==3942== by 0x4632A20: rsvg::xml::xml2_load::sax_entity_decl_cb (xml2_load.rs:168) +==3942== by 0x5B4FC16: xmlParseEntityDecl (parser.c:5495) +==3942== by 0x5B50A91: xmlParseInternalSubset (parser.c:8027) +==3942== by 0x5B5188E: xmlParseDocument (parser.c:10439) +==3942== by 0x463164B: ::parse (xml2_load.rs:471) +==3942== by 0x45E0B90: ::parse_from_stream::{closure#0} (mod.rs:648) +==3942== by 0x45916BF: , rsvg::error::LoadingError>>::and_then::<(), ::parse_from_stream::{closure#0}> (library/core/src/result.rs:1493) +==3942== by 0x45E2B54: ::parse_from_stream (mod.rs:648) +==3942== by 0x45E121D: ::acquire_xml (mod.rs:631) +==3942== by 0x45E1682: ::include_xml (mod.rs:578) +==3942== Block was alloc'd at +==3942== at 0x578C958: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) +==3942== by 0x5B78C60: xmlStrndup (xmlstring.c:54) +==3942== by 0x5B36A03: xmlCreateEntity (entities.c:151) +==3942== by 0x4632994: rsvg::xml::xml2_load::sax_entity_decl_cb (xml2_load.rs:157) +==3942== by 0x5B4FC16: xmlParseEntityDecl (parser.c:5495) +==3942== by 0x5B50A91: xmlParseInternalSubset (parser.c:8027) +==3942== by 0x5B5188E: xmlParseDocument (parser.c:10439) +==3942== by 0x463164B: ::parse (xml2_load.rs:471) +==3942== by 0x45E0B90: ::parse_from_stream::{closure#0} (mod.rs:648) +==3942== by 0x45916BF: , rsvg::error::LoadingError>>::and_then::<(), ::parse_from_stream::{closure#0}> (library/core/src/result.rs:1493) +==3942== by 0x45E2B54: ::parse_from_stream (mod.rs:648) +==3942== by 0x45E25FF: ::build_document (mod.rs:661) +==3942== by 0x45E667B: rsvg::xml::xml_load_from_possibly_compressed_stream (mod.rs:764) +==3942== by 0x46F3DC1: ::load_from_stream (document.rs:216) +==3942== by 0x44A97FC: ::read_stream:: (api.rs:303) +==3942== by 0x44824A7: ::convert (main.rs:585) + +Fixes https://gitlab.gnome.org/GNOME/librsvg/-/work_items/1241 + +Part-of: +--- + rsvg/src/xml/mod.rs | 35 ++++++++++++++++++++++++++++++----- + rsvg/src/xml/xml2_load.rs | 16 ++++------------ + 2 files changed, 34 insertions(+), 17 deletions(-) + +--- librsvg-2.60.0+dfsg.orig/rsvg/src/xml/mod.rs ++++ librsvg-2.60.0+dfsg/rsvg/src/xml/mod.rs +@@ -10,7 +10,8 @@ use markup5ever::{ + expanded_name, local_name, namespace_url, ns, ExpandedName, LocalName, Namespace, QualName, + }; + use std::cell::RefCell; +-use std::collections::HashMap; ++use std::collections::{HashMap, hash_map::Entry}; ++use std::ptr; + use std::rc::Rc; + use std::str; + use std::string::ToString; +@@ -31,6 +32,7 @@ use crate::session::Session; + use crate::style::StyleType; + use crate::url_resolver::AllowedUrl; + ++use xml2::xmlNewEntity; + use xml2_load::Xml2Parser; + + mod attributes; +@@ -362,12 +364,35 @@ impl XmlState { + .map(|entity| entity.0) + } + +- pub fn entity_insert(&self, entity_name: &str, entity: xmlEntityPtr) { ++ pub fn entity_insert( ++ &self, ++ entity_name: &str, ++ xml_entity_name: *const libc::c_char, ++ type_: libc::c_int, ++ content: *const libc::c_char, ++ ) { + let mut inner = self.inner.borrow_mut(); + +- inner +- .entities +- .insert(entity_name.to_string(), XmlEntity(entity)); ++ match inner.entities.entry(entity_name.to_string()) { ++ Entry::Occupied(_) => { ++ // Ignore the case where an entity is declared twice with the ++ // same name. ++ } ++ ++ Entry::Vacant(v) => unsafe { ++ let entity = xmlNewEntity( ++ ptr::null_mut(), ++ xml_entity_name, ++ type_, ++ ptr::null(), ++ ptr::null(), ++ content, ++ ); ++ assert!(!entity.is_null()); ++ ++ v.insert(XmlEntity(entity)); ++ }, ++ } + } + + fn element_creation_start_element(&self, name: &QualName, attrs: Attributes) -> Context { +--- librsvg-2.60.0+dfsg.orig/rsvg/src/xml/xml2_load.rs ++++ librsvg-2.60.0+dfsg/rsvg/src/xml/xml2_load.rs +@@ -149,18 +149,10 @@ unsafe extern "C" fn sax_entity_decl_cb( + return; + } + +- let entity = xmlNewEntity( +- ptr::null_mut(), +- name, +- type_, +- ptr::null(), +- ptr::null(), +- content, +- ); +- assert!(!entity.is_null()); +- +- let name = utf8_cstr(name); +- xml2_parser.state.entity_insert(name, entity); ++ let str_name = utf8_cstr(name); ++ xml2_parser ++ .state ++ .entity_insert(str_name, name, type_, content); + } + + unsafe extern "C" fn sax_unparsed_entity_decl_cb( diff -Nru librsvg-2.60.0+dfsg/debian/patches/series librsvg-2.60.0+dfsg/debian/patches/series --- librsvg-2.60.0+dfsg/debian/patches/series 2025-03-19 12:29:39.000000000 +0000 +++ librsvg-2.60.0+dfsg/debian/patches/series 2026-10-06 22:03:53.000000000 +0000 @@ -5,3 +5,4 @@ workarounds/Skip-invalid_viewbox-test-on-32-bit-x86.patch workarounds/tests-Skip-known-failing-tests-on-i386.patch workarounds/Temporarily-disable-rtl-span-reftest-which-fails-with-Pan.patch +CVE-2026-96889.patch