Package: mupdf Version: 1.25.1+ds1-6 Tags: patch security Justification: remote DoS via infinite recursion Followup-For: Bug #1110482 Usertags: cve-2025-46206 Control: tags -1 patch
Dear Maintainer, This non-maintainer upload (NMU) provides a backported patch for CVE-2025-46206 in the mupdf package for Debian Trixie. The vulnerability allows a remote attacker to trigger infinite recursion in `mutool clean` by crafting a PDF with cyclic `/Next` references in the outline structure, causing the process to crash and potentially exhaust system resources. Upstream has fixed this issue in commit https://cgit.ghostscript.com/cgi-bin/cgit.cgi/mupdf.git/commit/?id=0ec7e4d2201bb6df217e01c17396d36297abf9ac. This patch incorporates that change into version 1.25.1+ds1-7. Reproduction is straightforward using the upstream PoC from Bug 708521, and testing confirms that with the patch the crash and core dump no longer occur. Please consider including this fix or let me know if further information or packaging adjustments are required. Best regards, Yang Wang <[email protected]> -- System Information: Debian Release: 13.0 APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 5.15.0-138-generic (SMP w/88 CPU threads) Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C), LANGUAGE not set Shell: /bin/sh linked to /usr/bin/dash Init: unable to detect Versions of packages mupdf depends on: ii libc6 2.41-10 ii libgl1 1.7.0-1+b2 ii libglut3.12 3.4.0-4 ii libjbig2dec0 0.20-1+b3 ii libjs-sphinxdoc 8.1.3-5 ii libmujs3 1.3.6-1 ii libmupdf25.1 1.25.1+ds1-6 ii libssl3t64 3.5.1-1 ii libx11-6 2:1.8.12-1 ii libxext6 2:1.3.4-1+b3 mupdf recommends no packages. Versions of packages mupdf suggests: ii mupdf-tools 1.25.1+ds1-6 -- no debconf information
diff -Nru mupdf-1.25.1+ds1/debian/changelog mupdf-1.25.1+ds1/debian/changelog --- mupdf-1.25.1+ds1/debian/changelog 2025-04-21 22:12:48.000000000 +0000 +++ mupdf-1.25.1+ds1/debian/changelog 2025-08-06 20:24:38.000000000 +0000 @@ -1,3 +1,12 @@ +mupdf (1.25.1+ds1-7) unstable; urgency=high + + * Non-maintainer upload. + * Fix CVE-2025-46206: Infinite recursion in `mutool clean` when processing + cyclic /Next references in PDF outlines. Backports upstream commit + 0ec7e4d2201bb6df217e01c17396d36297abf9ac which avoids outline-recursion cycles. + + -- Yang Wang <[email protected]> Wed, 06 Aug 2025 16:24:38 -0400 + mupdf (1.25.1+ds1-6) unstable; urgency=medium * Fix segfault when using get_text() on arm64 (Closes: #1100748) diff -Nru mupdf-1.25.1+ds1/debian/patches/fix-cve-2025-46206.patch mupdf-1.25.1+ds1/debian/patches/fix-cve-2025-46206.patch --- mupdf-1.25.1+ds1/debian/patches/fix-cve-2025-46206.patch 1970-01-01 00:00:00.000000000 +0000 +++ mupdf-1.25.1+ds1/debian/patches/fix-cve-2025-46206.patch 2025-08-06 20:24:38.000000000 +0000 @@ -0,0 +1,101 @@ +Description: Fix infinite recursion in mutool clean when processing PDF outlines with cyclic /Next references +Origin: upstream, commit https://cgit.ghostscript.com/cgi-bin/cgit.cgi/mupdf.git/commit/?id=0ec7e4d2201bb6df217e01c17396d36297abf9ac +Bug: https://bugs.ghostscript.com/show_bug.cgi?id=708521 +Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2025-46206 +Forwarded: yes +Author: Sebastian Rasmussen <[email protected]> (upstream) +Reviewed-by: Yang Wang <[email protected]> +Last-Update: 2025-08-06 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: mupdf-1.25.1+ds1/source/pdf/pdf-clean-file.c +=================================================================== +--- mupdf-1.25.1+ds1.orig/source/pdf/pdf-clean-file.c ++++ mupdf-1.25.1+ds1/source/pdf/pdf-clean-file.c +@@ -157,22 +157,25 @@ static int strip_stale_annot_refs(fz_con + } + } + +-static int strip_outlines(fz_context *ctx, pdf_document *doc, pdf_obj *outlines, int page_count, int *page_object_nums, pdf_obj *names_list); ++static int strip_outlines(fz_context *ctx, pdf_document *doc, pdf_obj *outlines, int page_count, int *page_object_nums, pdf_obj *names_list, pdf_mark_bits *marks); + +-static int strip_outline(fz_context *ctx, pdf_document *doc, pdf_obj *outlines, int page_count, int *page_object_nums, pdf_obj *names_list, pdf_obj **pfirst, pdf_obj **plast) ++static int strip_outline(fz_context *ctx, pdf_document *doc, pdf_obj *outlines, int page_count, int *page_object_nums, pdf_obj *names_list, pdf_obj **pfirst, pdf_obj **plast, pdf_mark_bits *marks) + { + pdf_obj *prev = NULL; + pdf_obj *first = NULL; + pdf_obj *current; + int count = 0; + ++ if (pdf_mark_bits_set(ctx, marks, outlines)) ++ fz_throw(ctx, FZ_ERROR_FORMAT, "Cycle detected in outlines"); ++ + for (current = outlines; current != NULL; ) + { + int nc; + + /* Strip any children to start with. This takes care of + * First/Last/Count for us. */ +- nc = strip_outlines(ctx, doc, current, page_count, page_object_nums, names_list); ++ nc = strip_outlines(ctx, doc, current, page_count, page_object_nums, names_list, marks); + + if (!dest_is_valid(ctx, current, page_count, page_object_nums, names_list)) + { +@@ -223,7 +226,7 @@ static int strip_outline(fz_context *ctx + return count; + } + +-static int strip_outlines(fz_context *ctx, pdf_document *doc, pdf_obj *outlines, int page_count, int *page_object_nums, pdf_obj *names_list) ++static int strip_outlines(fz_context *ctx, pdf_document *doc, pdf_obj *outlines, int page_count, int *page_object_nums, pdf_obj *names_list, pdf_mark_bits *marks) + { + int nc; + pdf_obj *first; +@@ -232,11 +235,14 @@ static int strip_outlines(fz_context *ct + if (!pdf_is_dict(ctx, outlines)) + return 0; + ++ if (pdf_mark_bits_set(ctx, marks, outlines)) ++ fz_throw(ctx, FZ_ERROR_FORMAT, "Cycle detected in outlines"); ++ + first = pdf_dict_get(ctx, outlines, PDF_NAME(First)); + if (!pdf_is_dict(ctx, first)) + nc = 0; + else +- nc = strip_outline(ctx, doc, first, page_count, page_object_nums, names_list, &first, &last); ++ nc = strip_outline(ctx, doc, first, page_count, page_object_nums, names_list, &first, &last, marks); + + if (nc == 0) + { +@@ -268,6 +274,7 @@ static void pdf_rearrange_pages_imp(fz_c + pdf_obj *structtreeroot; + pdf_obj *ostructparents; + pdf_obj *structparents = NULL; ++ pdf_mark_bits *marks = NULL; + + /* Keep only pages/type and (reduced) dest entries to avoid + * references to unretained pages */ +@@ -286,6 +293,7 @@ static void pdf_rearrange_pages_imp(fz_c + fz_var(allfields); + fz_var(page_object_nums); + fz_var(kids); ++ fz_var(marks); + + fz_try(ctx) + { +@@ -423,13 +431,15 @@ static void pdf_rearrange_pages_imp(fz_c + pdf_dict_del(ctx, f, PDF_NAME(A)); + } + +- if (strip_outlines(ctx, doc, outlines, pagecount, page_object_nums, names_list) == 0) ++ marks = pdf_new_mark_bits(ctx, doc); ++ if (strip_outlines(ctx, doc, outlines, pagecount, page_object_nums, names_list, marks) == 0) + { + pdf_dict_del(ctx, root, PDF_NAME(Outlines)); + } + } + fz_always(ctx) + { ++ pdf_drop_mark_bits(ctx, marks); + fz_free(ctx, page_object_nums); + pdf_drop_obj(ctx, allfields); + pdf_drop_obj(ctx, root); diff -Nru mupdf-1.25.1+ds1/debian/patches/series mupdf-1.25.1+ds1/debian/patches/series --- mupdf-1.25.1+ds1/debian/patches/series 2025-04-21 22:12:48.000000000 +0000 +++ mupdf-1.25.1+ds1/debian/patches/series 2025-08-06 20:24:38.000000000 +0000 @@ -9,3 +9,4 @@ 0008-define-SONAME-header.patch 0008-Add-fallback-for-missing-SA_NOCLDWAIT.patch 0009-Use-Charis-SIL-ttf-font-directly.patch +fix-cve-2025-46206.patch

