From c90a86e5c02fc3f746391e10f2e07f1349ed08ab Mon Sep 17 00:00:00 2001 From: Xiongbing <3251316564@qq.com> Date: Tue, 5 Dec 2023 18:38:08 +0800 Subject: [PATCH] =?UTF-8?q?CVE-2020-16303=20Artifex=20Software=20Ghostscri?= =?UTF-8?q?pt=20v9.50=E7=89=88=E6=9C=AC=E4=B8=AD=E7=9A=84devices/vector/gd?= =?UTF-8?q?evxps.c=E6=96=87=E4=BB=B6=E7=9A=84xps=5Ffinish=5Fimage=5Fpath()?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E8=B5=84=E6=BA=90=E7=AE=A1=E7=90=86=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...r-handling-of-error-during-PS-PDF-im.patch | 98 +++++++++++++++++++ debian/changelog | 1 - devices/vector/gdevxps.c | 43 +++++--- 3 files changed, 128 insertions(+), 14 deletions(-) create mode 100644 0001-Bug-701818-better-handling-of-error-during-PS-PDF-im.patch diff --git a/0001-Bug-701818-better-handling-of-error-during-PS-PDF-im.patch b/0001-Bug-701818-better-handling-of-error-during-PS-PDF-im.patch new file mode 100644 index 0000000..adf2513 --- /dev/null +++ b/0001-Bug-701818-better-handling-of-error-during-PS-PDF-im.patch @@ -0,0 +1,98 @@ +From 94d8955cb7725eb5f3557ddc02310c76124fdd1a Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Mon, 4 Nov 2019 14:23:30 +0000 +Subject: [PATCH] Bug 701818: better handling of error during PS/PDF image + +In the xps device, if an error occurred after xps_begin_image() but before +xps_image_end_image(), *if* the Postscript had called 'restore' as part of the +error handling, the image enumerator would have been freed (by the restore) +despite the xps device still holding a reference to it. + +Simply changing to an allocator unaffected save/restore doesn't work because +the enumerator holds references to other objects (graphics state, color space, +possibly others) whose lifespans are inherently controlled by save/restore. + +So, add a finalize method for the XPS device's image enumerator +(xps_image_enum_finalize()) which takes over cleaning up the memory it allocates +and also deals with cleaning up references from the device to the enumerator +and from the enumerator to the device. +--- + devices/vector/gdevxps.c | 43 ++++++++++++++++++++++++++++------------ + 1 file changed, 30 insertions(+), 13 deletions(-) + +diff --git a/devices/vector/gdevxps.c b/devices/vector/gdevxps.c +index 71ca1f745..5d98c283a 100644 +--- a/devices/vector/gdevxps.c ++++ b/devices/vector/gdevxps.c +@@ -152,9 +152,12 @@ typedef struct xps_image_enum_s { + gp_file *fid; + } xps_image_enum_t; + +-gs_private_st_suffix_add4(st_xps_image_enum, xps_image_enum_t, ++static void ++xps_image_enum_finalize(const gs_memory_t *cmem, void *vptr); ++ ++gs_private_st_suffix_add4_final(st_xps_image_enum, xps_image_enum_t, + "xps_image_enum_t", xps_image_enum_enum_ptrs, +- xps_image_enum_reloc_ptrs, st_vector_image_enum, ++ xps_image_enum_reloc_ptrs, xps_image_enum_finalize, st_vector_image_enum, + buffer, devc_buffer, pcs, pgs); + + typedef struct gx_device_xps_s { +@@ -1424,6 +1427,11 @@ xps_finish_image_path(gx_device_vector *vdev) + const char *fmt; + gs_matrix matrix; + ++ /* If an error occurs during an image, we can get here after the enumerator ++ * has been freed - if that's the case, just bail out immediately ++ */ ++ if (xps->xps_pie == NULL) ++ return; + /* Path is started. Do the image brush image brush and close the path */ + write_str_to_current_page(xps, "\t\n"); + write_str_to_current_page(xps, "\t\tpcs != NULL) +- rc_decrement(pie->pcs, "xps_image_end_image (pcs)"); +- if (pie->buffer != NULL) +- gs_free_object(pie->memory, pie->buffer, "xps_image_end_image"); +- if (pie->devc_buffer != NULL) +- gs_free_object(pie->memory, pie->devc_buffer, "xps_image_end_image"); +- +- /* ICC clean up */ +- if (pie->icc_link != NULL) +- gsicc_release_link(pie->icc_link); +- + return code; + } + +@@ -2485,3 +2482,23 @@ tiff_from_name(gx_device_xps *dev, const char *name, int big_endian, bool usebig + xps_tifsDummyUnmapProc); + return t; + } ++ ++static void ++xps_image_enum_finalize(const gs_memory_t *cmem, void *vptr) ++{ ++ xps_image_enum_t *xpie = (xps_image_enum_t *)vptr; ++ gx_device_xps *xdev = (gx_device_xps *)xpie->dev; ++ ++ xpie->dev = NULL; ++ if (xpie->pcs != NULL) ++ rc_decrement(xpie->pcs, "xps_image_end_image (pcs)"); ++ if (xpie->buffer != NULL) ++ gs_free_object(xpie->memory, xpie->buffer, "xps_image_end_image"); ++ if (xpie->devc_buffer != NULL) ++ gs_free_object(xpie->memory, xpie->devc_buffer, "xps_image_end_image"); ++ ++ /* ICC clean up */ ++ if (xpie->icc_link != NULL) ++ gsicc_release_link(xpie->icc_link); ++ xdev->xps_pie = NULL; ++} +-- +2.25.1 + diff --git a/debian/changelog b/debian/changelog index 8525a9e..84510cc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -39,7 +39,6 @@ ghostscript (9.50~dfsg-ok2) yangtze; urgency=medium -- wengz Tue, 14 Mar 2023 15:42:43 +0800 ghostscript (9.50~dfsg-ok1) yangtze; urgency=medium - * Build for openKylin. -- openKylinBot Mon, 25 Apr 2022 22:03:04 +0800 diff --git a/devices/vector/gdevxps.c b/devices/vector/gdevxps.c index 71ca1f7..5d98c28 100644 --- a/devices/vector/gdevxps.c +++ b/devices/vector/gdevxps.c @@ -152,9 +152,12 @@ typedef struct xps_image_enum_s { gp_file *fid; } xps_image_enum_t; -gs_private_st_suffix_add4(st_xps_image_enum, xps_image_enum_t, +static void +xps_image_enum_finalize(const gs_memory_t *cmem, void *vptr); + +gs_private_st_suffix_add4_final(st_xps_image_enum, xps_image_enum_t, "xps_image_enum_t", xps_image_enum_enum_ptrs, - xps_image_enum_reloc_ptrs, st_vector_image_enum, + xps_image_enum_reloc_ptrs, xps_image_enum_finalize, st_vector_image_enum, buffer, devc_buffer, pcs, pgs); typedef struct gx_device_xps_s { @@ -1424,6 +1427,11 @@ xps_finish_image_path(gx_device_vector *vdev) const char *fmt; gs_matrix matrix; + /* If an error occurs during an image, we can get here after the enumerator + * has been freed - if that's the case, just bail out immediately + */ + if (xps->xps_pie == NULL) + return; /* Path is started. Do the image brush image brush and close the path */ write_str_to_current_page(xps, "\t\n"); write_str_to_current_page(xps, "\t\tpcs != NULL) - rc_decrement(pie->pcs, "xps_image_end_image (pcs)"); - if (pie->buffer != NULL) - gs_free_object(pie->memory, pie->buffer, "xps_image_end_image"); - if (pie->devc_buffer != NULL) - gs_free_object(pie->memory, pie->devc_buffer, "xps_image_end_image"); - - /* ICC clean up */ - if (pie->icc_link != NULL) - gsicc_release_link(pie->icc_link); - return code; } @@ -2485,3 +2482,23 @@ tiff_from_name(gx_device_xps *dev, const char *name, int big_endian, bool usebig xps_tifsDummyUnmapProc); return t; } + +static void +xps_image_enum_finalize(const gs_memory_t *cmem, void *vptr) +{ + xps_image_enum_t *xpie = (xps_image_enum_t *)vptr; + gx_device_xps *xdev = (gx_device_xps *)xpie->dev; + + xpie->dev = NULL; + if (xpie->pcs != NULL) + rc_decrement(xpie->pcs, "xps_image_end_image (pcs)"); + if (xpie->buffer != NULL) + gs_free_object(xpie->memory, xpie->buffer, "xps_image_end_image"); + if (xpie->devc_buffer != NULL) + gs_free_object(xpie->memory, xpie->devc_buffer, "xps_image_end_image"); + + /* ICC clean up */ + if (xpie->icc_link != NULL) + gsicc_release_link(xpie->icc_link); + xdev->xps_pie = NULL; +}