ghostscript: patch CVE-2025-59798

Pick commit mentioned in the NVD report.

(From OE-Core rev: 4a2f47d9541d7a13da7a9ce16bd5088870c45ec4)

Signed-off-by: Peter Marko <peter.marko@siemens.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
This commit is contained in:
Peter Marko
2025-10-08 00:11:10 +02:00
committed by Steve Sakoman
parent 8a80300d0f
commit 7698e2910d
2 changed files with 135 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
From 0cae41b23a9669e801211dd4cf97b6dadd6dbdd7 Mon Sep 17 00:00:00 2001
From: Ken Sharp <Ken.Sharp@artifex.com>
Date: Thu, 22 May 2025 12:25:41 +0100
Subject: [PATCH] pdfwrite - avoid buffer overrun
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.
CVE: CVE-2025-59798
Upstream-Status: Backport [https://github.com/ArtifexSoftware/ghostpdl/commit/0cae41b23a9669e801211dd4cf97b6dadd6dbdd7]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
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 ced15c9b2..fe24dd73a 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). */

View File

@@ -25,6 +25,7 @@ def gs_verdir(v):
SRC_URI = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs${@gs_verdir("${PV}")}/${BPN}-${PV}.tar.gz \ SRC_URI = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs${@gs_verdir("${PV}")}/${BPN}-${PV}.tar.gz \
file://ghostscript-9.16-Werror-return-type.patch \ file://ghostscript-9.16-Werror-return-type.patch \
file://avoid-host-contamination.patch \ file://avoid-host-contamination.patch \
file://CVE-2025-59798.patch \
" "
SRC_URI[sha256sum] = "121861b6d29b2461dec6575c9f3cab665b810bd408d4ec02c86719fa708b0a49" SRC_URI[sha256sum] = "121861b6d29b2461dec6575c9f3cab665b810bd408d4ec02c86719fa708b0a49"