librsvg 巢狀 XInclude 重複實體引發 UAF
RustSec · 2026-09-23
漏洞機制
RustSec 公告 RUSTSEC-2026-0305(對應 CVE-2026-96889)指出,librsvg 在解析含有巢狀 xi:include 的 SVG 文件時,如果被載入的子文件重新宣告了一個「與外層解析器正在展開的實體同名」的 XML 實體,就會觸發釋放後再使用(use-after-free)。關鍵在於:遞迴的 XInclude 解析會另外載入一份文件,而那份文件與外層解析共用同一份 XmlState 實體對照表。當內層解析呼叫 entity_insert() 寫入同名項目時,會直接覆蓋外層仍在使用中的舊項目。
問題出在覆蓋動作本身:舊實體物件的 Rust Drop 實作會呼叫 libxml2 的 xmlFreeNode() 把底層節點釋放掉,但外層的 xmlCtxtParseEntity() 此時仍握著同一塊記憶體的指標並繼續存取。GNOME 團隊的分析描述,外層解析器接著會讀寫一個已釋放、大小為 144 位元組的 xmlEntity 結構。官方釋出的概念性驗證檔案顯示,只要在 xi:include 內用 data URI 內嵌另一份 SVG,並在其中重新宣告一個仍在展開中的實體名稱,即可穩定觸發此狀況。
受影響版本
公告點名的受影響套件是 crates.io 上的 librsvg,也就是 GNOME 用來把 SVG 轉成點陣圖、供 GTK 圖示與桌面元件渲染用的核心函式庫。受影響與已修補的版本範圍如下,官方公告未提供 CVSS 分數:
- 受影響:
librsvg低於2.63.2 - 受影響:
librsvg 2.62.0至2.62.3(即低於2.62.4的 2.62.x 系列) - 已修補:
librsvg >= 2.63.2 - 已修補:
librsvg >= 2.62.4, < 2.62.90
由於 librsvg 是 GTK/GNOME 生態渲染 SVG 圖示與向量圖的底層元件,任何會把不信任來源的 SVG 交給 librsvg 解析的桌面應用或服務都在受影響範圍內,不只是直接呼叫這個 Rust crate 的專案。攻擊者只需準備一份帶有巢狀 XInclude 與重複實體名稱的 SVG,就有機會讓渲染流程存取已釋放記憶體。
修補與緩解
修補由提交 8a1b0cd319e9af2d1e9cf878081dd77f227a0504 完成,做法是不再讓 librsvg 自己釋放仍被 libxml2 使用中的 xmlEntity 指標,改由雙方協調實體物件的存活期間,避免內層解析覆蓋實體時提前釋放外層仍在讀取的節點。這是修正所有權邊界而非單純加上檢查,因此不會影響正常 SVG 的解析結果。
對使用 librsvg 的專案而言,該做的事很直接:把依賴升級到 librsvg >= 2.63.2,若卡在 2.62 系列則升到 >= 2.62.4。GNOME 桌面環境與任何透過 librsvg 產生圖示縮圖、預覽或轉檔的服務,都應把此更新視為記憶體安全修補,優先排入更新排程,尤其是會處理使用者上傳或外部來源 SVG 檔案的路徑。
原始來源:RustSec Advisory RUSTSEC-2026-0305、GNOME GitLab work item #1241