new file mode 100644
@@ -0,0 +1,308 @@
+Backport of:
+Note: updated to fix compiler warning.
+
+From ff1013a0ab485b66783b70145e342a82c670906a Mon Sep 17 00:00:00 2001
+From: Ken Sharp <Ken.Sharp@artifex.com>
+Date: Thu, 25 Jan 2024 11:53:44 +0000
+Subject: Bug 707510 - review printing of pointers
+
+This is for item 4 of the report, which is addressed by the change in
+gdevpdtb.c. That change uses a fixed name for fonts which have no name
+instead of using the pointer to the address of the font.
+
+The remaining changes are all due to reviewing the use of PRI_INTPTR.
+In general we only use that for debugging purposes but there were a few
+places which were printing pointers arbitrarily, even in a release build.
+
+We really don't want to do that so I've modified the places which were
+printing pointer unconditionally so that they only do so if DEBUG is
+set at compile time, or a specific debug flag is set.
+
+CVE: CVE-2024-29508
+Upstream-Status: Backport [https://git.launchpad.net/ubuntu/+source/ghostscript/commit/?h=ubuntu/focal-security&id=22b23aa6de7613a4d9c1da9c84d72427c9d0cf1a]
+Upstream commit: https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=ff1013a0ab485b66783b70145e342a82c670906a
+Signed-off-by: Ashish Sharma <asharma@mvista.com>
+
+ base/gsfont.c | 4 ++--
+ base/gsicc_cache.c | 8 ++++----
+ base/gsmalloc.c | 4 ++--
+ base/gxclmem.c | 5 ++---
+ base/gxcpath.c | 6 +++++-
+ base/gxpath.c | 8 +++++++-
+ base/szlibc.c | 4 +++-
+ devices/gdevupd.c | 7 ++++++-
+ devices/vector/gdevpdtb.c | 4 ++--
+ psi/ialloc.c | 4 ++--
+ psi/igc.c | 6 +++---
+ psi/igcstr.c | 6 +++---
+ psi/iinit.c | 6 +++++-
+ psi/imainarg.c | 5 +++--
+ psi/isave.c | 4 ++--
+ psi/iutil.c | 6 +++++-
+ 16 files changed, 56 insertions(+), 31 deletions(-)
+
+--- a/base/gsfont.c
++++ b/base/gsfont.c
+@@ -778,7 +778,7 @@ gs_purge_font(gs_font * pfont)
+ else if (pdir->scaled_fonts == pfont)
+ pdir->scaled_fonts = next;
+ else { /* Shouldn't happen! */
+- lprintf1("purged font "PRI_INTPTR" not found\n", (intptr_t)pfont);
++ if_debug1m('u', pfont->memory, "purged font "PRI_INTPTR" not found\n", (intptr_t)pfont);
+ }
+
+ /* Purge the font from the scaled font cache. */
+--- a/base/gsicc_cache.c
++++ b/base/gsicc_cache.c
+@@ -149,7 +149,7 @@ icc_linkcache_finalize(const gs_memory_t
+
+ while (link_cache->head != NULL) {
+ if (link_cache->head->ref_count != 0) {
+- emprintf2(mem, "link at "PRI_INTPTR" being removed, but has ref_count = %d\n",
++ if_debug2m(gs_debug_flag_icc, mem, "link at "PRI_INTPTR" being removed, but has ref_count = %d\n",
+ (intptr_t)link_cache->head, link_cache->head->ref_count);
+ link_cache->head->ref_count = 0; /* force removal */
+ }
+@@ -560,7 +560,7 @@ gsicc_findcachelink(gsicc_hashlink_t has
+ /* that was building it failed to be able to complete building it */
+ /* this is probably a fatal error. MV ??? */
+ if (curr->valid == false) {
+- emprintf1(curr->memory, "link "PRI_INTPTR" lock released, but still not valid.\n", (intptr_t)curr); /* Breakpoint here */
++ if_debug1m(gs_debug_flag_icc, curr->memory, "link "PRI_INTPTR" lock released, but still not valid.\n", (intptr_t)curr); /* Breakpoint here */
+ }
+ gx_monitor_enter(icc_link_cache->lock); /* re-enter to loop and check */
+ }
+@@ -587,7 +587,7 @@ gsicc_remove_link(gsicc_link_t *link, co
+ /* NOTE: link->ref_count must be 0: assert ? */
+ gx_monitor_enter(icc_link_cache->lock);
+ if (link->ref_count != 0) {
+- emprintf2(memory, "link at "PRI_INTPTR" being removed, but has ref_count = %d\n", (intptr_t)link, link->ref_count);
++ if_debug2m(gs_debug_flag_icc, memory, "link at "PRI_INTPTR" being removed, but has ref_count = %d\n", (intptr_t)link, link->ref_count);
+ }
+ curr = icc_link_cache->head;
+ prev = NULL;
+--- a/base/gsmalloc.c
++++ b/base/gsmalloc.c
+@@ -419,7 +419,7 @@ gs_heap_resize_string(gs_memory_t * mem,
+ client_name_t cname)
+ {
+ if (gs_heap_object_type(mem, data) != &st_bytes)
+- lprintf2("%s: resizing non-string "PRI_INTPTR"!\n",
++ if_debug2m('a', mem, "%s: resizing non-string "PRI_INTPTR"!\n",
+ client_name_string(cname), (intptr_t)data);
+ return gs_heap_resize_object(mem, data, new_num, cname);
+ }
+--- a/base/gxclmem.c
++++ b/base/gxclmem.c
+@@ -490,8 +490,7 @@ memfile_fclose(clist_file_ptr cf, const
+ /* leaks if other users of the memfile don't 'fclose with delete=true */
+ if (f->openlist != NULL || ((f->base_memfile != NULL) && f->base_memfile->is_open)) {
+ /* TODO: do the cleanup rather than just giving an error */
+- emprintf1(f->memory,
+- "Attempt to delete a memfile still open for read: "PRI_INTPTR"\n",
++ if_debug1(':', "Attempt to delete a memfile still open for read: "PRI_INTPTR"\n",
+ (intptr_t)f);
+ return_error(gs_error_invalidfileaccess);
+ } else {
+--- a/base/gxcpath.c
++++ b/base/gxcpath.c
+@@ -172,8 +172,10 @@ gx_cpath_init_contained_shared(gx_clip_p
+ {
+ if (shared) {
+ if (shared->path.segments == &shared->path.local_segments) {
++#ifdef DEBUG
+ lprintf1("Attempt to share (local) segments of clip path "PRI_INTPTR"!\n",
+ (intptr_t)shared);
++#endif
+ return_error(gs_error_Fatal);
+ }
+ *pcpath = *shared;
+@@ -230,8 +232,10 @@ gx_cpath_init_local_shared_nested(gx_cli
+ if (shared) {
+ if ((shared->path.segments == &shared->path.local_segments) &&
+ !safely_nested) {
++#ifdef DEBUG
+ lprintf1("Attempt to share (local) segments of clip path "PRI_INTPTR"!\n",
+ (intptr_t)shared);
++#endif
+ return_error(gs_error_Fatal);
+ }
+ pcpath->path = shared->path;
+--- a/base/gxpath.c
++++ b/base/gxpath.c
+@@ -137,8 +137,10 @@ gx_path_init_contained_shared(gx_path *
+ {
+ if (shared) {
+ if (shared->segments == &shared->local_segments) {
++#ifdef DEBUG
+ lprintf1("Attempt to share (local) segments of path "PRI_INTPTR"!\n",
+ (intptr_t)shared);
++#endif
+ return_error(gs_error_Fatal);
+ }
+ *ppath = *shared;
+@@ -172,8 +174,10 @@ gx_path_alloc_shared(const gx_path * sha
+ ppath->procs = &default_path_procs;
+ if (shared) {
+ if (shared->segments == &shared->local_segments) {
++#ifdef DEBUG
+ lprintf1("Attempt to share (local) segments of path "PRI_INTPTR"!\n",
+ (intptr_t)shared);
++#endif
+ gs_free_object(mem, ppath, cname);
+ return 0;
+ }
+@@ -203,8 +207,10 @@ gx_path_init_local_shared(gx_path * ppat
+ {
+ if (shared) {
+ if (shared->segments == &shared->local_segments) {
++#ifdef DEBUG
+ lprintf1("Attempt to share (local) segments of path "PRI_INTPTR"!\n",
+ (intptr_t)shared);
++#endif
+ return_error(gs_error_Fatal);
+ }
+ *ppath = *shared;
+--- a/base/szlibc.c
++++ b/base/szlibc.c
+@@ -110,7 +110,9 @@ s_zlib_free(void *zmem, void *data)
+ gs_free_object(mem, data, "s_zlib_free(data)");
+ for (; ; block = block->next) {
+ if (block == 0) {
++#ifdef DEBUG
+ lprintf1("Freeing unrecorded data "PRI_INTPTR"!\n", (intptr_t)data);
++#endif
+ return;
+ }
+ if (block->data == data)
+--- a/devices/gdevupd.c
++++ b/devices/gdevupd.c
+@@ -1039,8 +1039,13 @@ upd_print_page(gx_device_printer *pdev,
+ */
+ if(!upd || B_OK4GO != (upd->flags & (B_OK4GO | B_ERROR))) {
+ #if UPD_MESSAGES & (UPD_M_ERROR | UPD_M_TOPCALLS)
++#ifdef DEBUG
+ errprintf(pdev->memory, "CALL-REJECTED upd_print_page(" PRI_INTPTR "," PRI_INTPTR ")\n",
+ (intptr_t)udev,(intptr_t) out);
++#else
++ errprintf(pdev->memory, "CALL-REJECTED upd_print_page\n",
++ (intptr_t)udev,(intptr_t) out);
++#endif
+ #endif
+ return_error(gs_error_undefined);
+ }
+--- a/devices/vector/gdevpdtb.c
++++ b/devices/vector/gdevpdtb.c
+@@ -371,7 +371,7 @@ pdf_base_font_alloc(gx_device_pdf *pdev,
+ font_name.size -= SUBSET_PREFIX_SIZE;
+ }
+ } else {
+- gs_sprintf(fnbuf, ".F" PRI_INTPTR, (intptr_t)copied);
++ gs_snprintf(fnbuf, sizeof(fnbuf), "Anonymous");
+ font_name.data = (byte *)fnbuf;
+ font_name.size = strlen(fnbuf);
+ }
+--- a/psi/ialloc.c
++++ b/psi/ialloc.c
+@@ -386,7 +386,7 @@ gs_free_ref_array(gs_ref_memory_t * mem,
+ size = num_refs * sizeof(ref);
+ break;
+ default:
+- lprintf3("Unknown type 0x%x in free_ref_array(%u,"PRI_INTPTR")!",
++ if_debug3('A', "Unknown type 0x%x in free_ref_array(%u,"PRI_INTPTR")!",
+ r_type(parr), num_refs, (intptr_t)obj);
+ return;
+ }
+--- a/psi/igc.c
++++ b/psi/igc.c
+@@ -1061,7 +1061,7 @@ gc_extend_stack(gc_mark_stack * pms, gc_
+
+ if (cp == 0) { /* We were tracing outside collectible */
+ /* storage. This can't happen. */
+- lprintf1("mark stack overflowed while outside collectible space at "PRI_INTPTR"!\n",
++ if_debug1('6', "mark stack overflowed while outside collectible space at "PRI_INTPTR"!\n",
+ (intptr_t)cptr);
+ gs_abort(pstate->heap);
+ }
+@@ -1290,7 +1290,7 @@ igc_reloc_struct_ptr(const void /*obj_he
+
+ if (cp != 0 && cp->cbase <= (byte *)obj && (byte *)obj <cp->ctop) {
+ if (back > (cp->ctop - cp->cbase) >> obj_back_shift) {
+- lprintf2("Invalid back pointer %u at "PRI_INTPTR"!\n",
++ if_debug2('6', "Invalid back pointer %u at "PRI_INTPTR"!\n",
+ back, (intptr_t)obj);
+ gs_abort(NULL);
+ }
+--- a/psi/igcstr.c
++++ b/psi/igcstr.c
+@@ -152,7 +152,7 @@ gc_string_mark(const byte * ptr, uint si
+ return false;
+ #ifdef DEBUG
+ if (ptr - HDR_ID_OFFSET < cp->ctop) {
+- lprintf4("String pointer "PRI_INTPTR"[%u] outside ["PRI_INTPTR".."PRI_INTPTR")\n",
++ if_debug4('6', "String pointer "PRI_INTPTR"[%u] outside ["PRI_INTPTR".."PRI_INTPTR")\n",
+ (intptr_t)ptr - HDR_ID_OFFSET, size, (intptr_t)cp->ctop, (intptr_t)cp->climit);
+ return false;
+ } else if (ptr + size > cp->climit) { /*
+@@ -171,7 +171,7 @@ gc_string_mark(const byte * ptr, uint si
+ while (ptr - HDR_ID_OFFSET == scp->climit && scp->outer != 0)
+ scp = scp->outer;
+ if (ptr - HDR_ID_OFFSET + size > scp->climit) {
+- lprintf4("String pointer "PRI_INTPTR"[%u] outside ["PRI_INTPTR".."PRI_INTPTR")\n",
++ if_debug4('6', "String pointer "PRI_INTPTR"[%u] outside ["PRI_INTPTR".."PRI_INTPTR")\n",
+ (intptr_t)ptr - HDR_ID_OFFSET, size,
+ (intptr_t)scp->ctop, (intptr_t)scp->climit);
+ return false;
+--- a/psi/iinit.c
++++ b/psi/iinit.c
+@@ -395,8 +395,12 @@ zop_init(i_ctx_t *i_ctx_p)
+ if (def->proc != 0) {
+ code = def->proc(i_ctx_p);
+ if (code < 0) {
++#ifdef DEBUG
+ lprintf2("op_init proc "PRI_INTPTR" returned error %d!\n",
+ (intptr_t)def->proc, code);
++#else
++ lprintf("op_init proc returned error !\n");
++#endif
+ return code;
+ }
+ }
+--- a/psi/imainarg.c
++++ b/psi/imainarg.c
+@@ -229,7 +229,8 @@ gs_main_init_with_args01(gs_main_instanc
+ if (gs_debug[':'] && !have_dumped_args) {
+ int i;
+
+- dmprintf1(minst->heap, "%% Args passed to instance "PRI_INTPTR": ",
++ if (gs_debug_c(gs_debug_flag_init_details))
++ dmprintf1(minst->heap, "%% Args passed to instance "PRI_INTPTR": ",
+ (intptr_t)minst);
+ for (i=1; i<argc; i++)
+ dmprintf1(minst->heap, "%s ", argv[i]);
+--- a/psi/isave.c
++++ b/psi/isave.c
+@@ -487,7 +487,7 @@ alloc_save_change_in(gs_ref_memory_t *me
+ else if (r_is_struct(pcont))
+ cp->offset = (byte *) where - (byte *) pcont->value.pstruct;
+ else {
+- lprintf3("Bad type %u for save! pcont = "PRI_INTPTR", where = "PRI_INTPTR"\n",
++ if_debug3('u', "Bad type %u for save! pcont = "PRI_INTPTR", where = "PRI_INTPTR"\n",
+ r_type(pcont), (intptr_t) pcont, (intptr_t) where);
+ gs_abort((const gs_memory_t *)mem);
+ }
+--- a/psi/iutil.c
++++ b/psi/iutil.c
+@@ -537,7 +537,11 @@ other:
+ break;
+ }
+ /* Internal operator, no name. */
+- gs_sprintf(buf, "@"PRI_INTPTR, (intptr_t) op->value.opproc);
++#ifdef DEBUG
++ gs_snprintf(buf, sizeof(buf), "@"PRI_INTPTR, (intptr_t) op->value.opproc);
++#else
++ gs_snprintf(buf, sizeof(buf), "@anonymous_operator", (intptr_t) op->value.opproc);
++#endif
+ break;
+ }
+ case t_real:
new file mode 100644
@@ -0,0 +1,29 @@
+From d084021e06ba1caa1373fbbcf24a8510f43830ab Mon Sep 17 00:00:00 2001
+From: Ken Sharp <Ken.Sharp@artifex.com>
+Date: Sat, 27 Jan 2024 09:30:30 +0000
+Subject: [PATCH] Coverity IDs 414141 & 414145
+
+These are the same problem reported two different ways. I forgot to
+remove the arguments to errprintf when I removed the format specifiers
+from the string as part of reviewing the pointer printing.
+
+CVE: CVE-2024-29508
+Upstream-Status: Backport [https://git.launchpad.net/ubuntu/+source/ghostscript/commit/?h=ubuntu/focal-security&id=22b23aa6de7613a4d9c1da9c84d72427c9d0cf1a]
+Upstream commit: https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=ff1013a0ab485b66783b70145e342a82c670906a
+Signed-off-by: Ashish Sharma <asharma@mvista.com>
+
+ devices/gdevupd.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/devices/gdevupd.c
++++ b/devices/gdevupd.c
+@@ -1043,8 +1043,7 @@ upd_print_page(gx_device_printer *pdev,
+ errprintf(pdev->memory, "CALL-REJECTED upd_print_page(" PRI_INTPTR "," PRI_INTPTR ")\n",
+ (intptr_t)udev,(intptr_t) out);
+ #else
+- errprintf(pdev->memory, "CALL-REJECTED upd_print_page\n",
+- (intptr_t)udev,(intptr_t) out);
++ errprintf(pdev->memory, "CALL-REJECTED upd_print_page\n");
+ #endif
+ #endif
+ return_error(gs_error_undefined);
@@ -54,6 +54,8 @@ SRC_URI_BASE = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/d
file://CVE-2024-29511-0002.patch \
file://CVE-2024-29509.patch \
file://CVE-2024-29506.patch \
+ file://CVE-2024-29508-1.patch \
+ file://CVE-2024-29508-2.patch \
"
SRC_URI = "${SRC_URI_BASE} \