Bug#1116443: ghostscript: diff for NMU version 10.05.1~dfsg-3.1
Control: tags 1116443 + patch
Control: tags 1116443 + pending
Control: tags 1116444 + patch
Control: tags 1116444 + pending
Dear Steve,
I've prepared an NMU for ghostscript (versioned as 10.05.1~dfsg-3.1) and
uploaded it to DELAYED/10. Please feel free to tell me if I
should cancel it.
The reason to upload it is I'm planning to do a DSA for bookworm and
trixie for those two issues and would want to ensure we have the fix
as well inthe upper suite.
If you are okay with the NMU and we can have it uploaded earlier to
the archive let me know, samewise if you are not ok with the NMU.
Maybe uploading the new upstream version would even be better.
Regards,
Salvatore
diffstat for ghostscript-10.05.1~dfsg ghostscript-10.05.1~dfsg
changelog | 8 +
patches/0004_pdfwrite-bounds-check-some-strings.patch | 43 +++++
patches/0005_pdfwrite-avoid-buffer-overrun.patch | 136 ++++++++++++++++++
patches/series | 2
4 files changed, 189 insertions(+)
diff -Nru ghostscript-10.05.1~dfsg/debian/changelog ghostscript-10.05.1~dfsg/debian/changelog
--- ghostscript-10.05.1~dfsg/debian/changelog 2025-09-07 04:25:01.000000000 +0200
+++ ghostscript-10.05.1~dfsg/debian/changelog 2025-09-28 16:45:34.000000000 +0200
@@ -1,3 +1,11 @@
+ghostscript (10.05.1~dfsg-3.1) unstable; urgency=medium
+
+ * Non-maintainer upload.
+ * pdfwrite - bounds check some strings (CVE-2025-59799) (Closes: #1116443)
+ * pdfwrite - avoid buffer overrun (CVE-2025-59798) (Closes: #1116444)
+
+ -- Salvatore Bonaccorso <carnil@debian.org> Sun, 28 Sep 2025 16:45:34 +0200
+
ghostscript (10.05.1~dfsg-3) unstable; urgency=medium
[ Steve Robbins ]
diff -Nru ghostscript-10.05.1~dfsg/debian/patches/0004_pdfwrite-bounds-check-some-strings.patch ghostscript-10.05.1~dfsg/debian/patches/0004_pdfwrite-bounds-check-some-strings.patch
--- ghostscript-10.05.1~dfsg/debian/patches/0004_pdfwrite-bounds-check-some-strings.patch 1970-01-01 01:00:00.000000000 +0100
+++ ghostscript-10.05.1~dfsg/debian/patches/0004_pdfwrite-bounds-check-some-strings.patch 2025-09-28 16:42:54.000000000 +0200
@@ -0,0 +1,43 @@
+From: Piotr Kajda <petermasterperfect@gmail.com>
+Date: Thu, 8 May 2025 11:37:09 +0100
+Subject: pdfwrite - bounds check some strings
+Origin: https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=6dab38fb211f15226c242ab7a83fa53e4b0ff781
+Bug: https://bugs.ghostscript.com/show_bug.cgi?id=708517
+Bug-Debian: https://bugs.debian.org/1116443
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-59799
+
+Bug #708517
+
+This differs very slightly from the proposed patch in the bug report, I
+had a quick scout through the C file and found another similar case.
+
+Both fixed here.
+---
+ devices/vector/gdevpdfm.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/devices/vector/gdevpdfm.c b/devices/vector/gdevpdfm.c
+index 5aa3644e2ec4..4b1d7d89c3e9 100644
+--- a/devices/vector/gdevpdfm.c
++++ b/devices/vector/gdevpdfm.c
+@@ -200,6 +200,8 @@ pdfmark_coerce_dest(gs_param_string *dstr, char dest[MAX_DEST_STRING])
+ {
+ const byte *data = dstr->data;
+ uint size = dstr->size;
++ if (size > MAX_DEST_STRING)
++ return_error(gs_error_limitcheck);
+ if (size == 0 || data[0] != '(')
+ return 0;
+ /****** HANDLE ESCAPES ******/
+@@ -868,6 +870,8 @@ pdfmark_put_ao_pairs(gx_device_pdf * pdev, cos_dict_t *pcd,
+ char buf[30];
+ int d0, d1;
+
++ if (Action[1].size > 29)
++ return_error(gs_error_rangecheck);
+ memcpy(buf, Action[1].data, Action[1].size);
+ buf[Action[1].size] = 0;
+ if (sscanf(buf, "%d %d R", &d0, &d1) == 2)
+--
+2.51.0
+
diff -Nru ghostscript-10.05.1~dfsg/debian/patches/0005_pdfwrite-avoid-buffer-overrun.patch ghostscript-10.05.1~dfsg/debian/patches/0005_pdfwrite-avoid-buffer-overrun.patch
--- ghostscript-10.05.1~dfsg/debian/patches/0005_pdfwrite-avoid-buffer-overrun.patch 1970-01-01 01:00:00.000000000 +0100
+++ ghostscript-10.05.1~dfsg/debian/patches/0005_pdfwrite-avoid-buffer-overrun.patch 2025-09-28 16:44:17.000000000 +0200
@@ -0,0 +1,136 @@
+From: Ken Sharp <Ken.Sharp@artifex.com>
+Date: Thu, 22 May 2025 12:25:41 +0100
+Subject: pdfwrite - avoid buffer overrun
+Origin: https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=0cae41b23a9669e801211dd4cf97b6dadd6dbdd7
+Bug: https://bugs.ghostscript.com/show_bug.cgi?id=708539
+Bug-Debian: https://bugs.debian.org/1116444
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-59798
+
+Bug #708539 "Buffer overflow in pdf_write_cmap"
+
+The proposed fix in the report solves the buffer overrun, but does not
+tackle a number of other problems.
+
+This commit checks the result of stream_puts() in
+pdf_write_cid_system_info_to_stream() and correctly signals an error to
+the caller if that fails.
+
+In pdf_write_cid_system_info we replace a (rather small!) fixed size
+buffer with a dynamically allocated one using the lengths of the strings
+which pdf_write_cid_system_info_to_stream() will write, and a small
+fixed overhead to deal with the keys and initial byte '/'.
+
+Because 'buf' is used in the stream 's', if it is too small to hold all
+the CIDSystemInfo then we would get an error which was simply discarded
+previously.
+
+We now should avoid the potential error by ensuring the buffer is large
+enough for all the information, and if we do get an error we no longer
+silently ignore it, which would write an invalid PDF file.
+---
+ devices/vector/gdevpdtw.c | 52 ++++++++++++++++++++++++++++++---------
+ 1 file changed, 41 insertions(+), 11 deletions(-)
+
+diff --git a/devices/vector/gdevpdtw.c b/devices/vector/gdevpdtw.c
+index ced15c9b2bbe..fe24dd73accf 100644
+--- a/devices/vector/gdevpdtw.c
++++ b/devices/vector/gdevpdtw.c
+@@ -703,7 +703,8 @@ static int
+ pdf_write_cid_system_info_to_stream(gx_device_pdf *pdev, stream *s,
+ const gs_cid_system_info_t *pcidsi, gs_id object_id)
+ {
+- byte *Registry, *Ordering;
++ byte *Registry = NULL, *Ordering = NULL;
++ int code = 0;
+
+ Registry = gs_alloc_bytes(pdev->pdf_memory, pcidsi->Registry.size, "temporary buffer for Registry");
+ if (!Registry)
+@@ -734,14 +735,19 @@ pdf_write_cid_system_info_to_stream(gx_device_pdf *pdev, stream *s,
+ }
+ s_arcfour_process_buffer(&sarc4, Ordering, pcidsi->Ordering.size);
+ }
+- stream_puts(s, "<<\n/Registry");
++ code = stream_puts(s, "<<\n/Registry");
++ if (code < 0)
++ goto error;
+ s_write_ps_string(s, Registry, pcidsi->Registry.size, PRINT_HEX_NOT_OK);
+- stream_puts(s, "\n/Ordering");
++ code = stream_puts(s, "\n/Ordering");
++ if(code < 0)
++ goto error;
+ s_write_ps_string(s, Ordering, pcidsi->Ordering.size, PRINT_HEX_NOT_OK);
++error:
+ pprintd1(s, "\n/Supplement %d\n>>\n", pcidsi->Supplement);
+ gs_free_object(pdev->pdf_memory, Registry, "free temporary Registry buffer");
+ gs_free_object(pdev->pdf_memory, Ordering, "free temporary Ordering buffer");
+- return 0;
++ return code;
+ }
+
+ int
+@@ -786,31 +792,55 @@ pdf_write_cmap(gx_device_pdf *pdev, const gs_cmap_t *pcmap,
+ *ppres = writer.pres;
+ writer.pres->where_used = 0; /* CMap isn't a PDF resource. */
+ if (!pcmap->ToUnicode) {
+- byte buf[200];
++ byte *buf = NULL;
++ uint64_t buflen = 0;
+ cos_dict_t *pcd = (cos_dict_t *)writer.pres->object;
+ stream s;
+
++ /* We use 'buf' for the stream 's' below and that needs to have some extra
++ * space for the CIDSystemInfo. We also need an extra byte for the leading '/'
++ * 100 bytes is ample for the overhead.
++ */
++ buflen = pcmap->CIDSystemInfo->Registry.size + pcmap->CIDSystemInfo->Ordering.size + pcmap->CMapName.size + 100;
++ if (buflen > max_uint)
++ return_error(gs_error_limitcheck);
++
++ buf = gs_alloc_bytes(pdev->memory, buflen, "pdf_write_cmap");
++ if (buf == NULL)
++ return_error(gs_error_VMerror);
++
+ code = cos_dict_put_c_key_int(pcd, "/WMode", pcmap->WMode);
+- if (code < 0)
++ if (code < 0) {
++ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
+ return code;
++ }
+ buf[0] = '/';
+ memcpy(buf + 1, pcmap->CMapName.data, pcmap->CMapName.size);
+ code = cos_dict_put_c_key_string(pcd, "/CMapName",
+ buf, pcmap->CMapName.size + 1);
+- if (code < 0)
++ if (code < 0) {
++ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
+ return code;
++ }
+ s_init(&s, pdev->memory);
+- swrite_string(&s, buf, sizeof(buf));
++ swrite_string(&s, buf, buflen);
+ code = pdf_write_cid_system_info_to_stream(pdev, &s, pcmap->CIDSystemInfo, 0);
+- if (code < 0)
++ if (code < 0) {
++ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
+ return code;
++ }
+ code = cos_dict_put_c_key_string(pcd, "/CIDSystemInfo",
+ buf, stell(&s));
+- if (code < 0)
++ if (code < 0) {
++ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
+ return code;
++ }
+ code = cos_dict_put_string_copy(pcd, "/Type", "/CMap");
+- if (code < 0)
++ if (code < 0) {
++ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
+ return code;
++ }
++ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
+ }
+ if (pcmap->CMapName.size == 0) {
+ /* Create an arbitrary name (for ToUnicode CMap). */
+--
+2.51.0
+
diff -Nru ghostscript-10.05.1~dfsg/debian/patches/series ghostscript-10.05.1~dfsg/debian/patches/series
--- ghostscript-10.05.1~dfsg/debian/patches/series 2025-09-07 04:25:01.000000000 +0200
+++ ghostscript-10.05.1~dfsg/debian/patches/series 2025-09-28 16:44:50.000000000 +0200
@@ -1,6 +1,8 @@
0001_CVE-2025-7462.patch
0002_fix-coverity.patch
0003_c23.patch
+0004_pdfwrite-bounds-check-some-strings.patch
+0005_pdfwrite-avoid-buffer-overrun.patch
1004_enable_spot_devices.patch
1005_simplify_ps2ascii.patch
2001_docdir_fix_for_debian.patch
Reply to: