From 28e708a4317d8372c60a0854d096819306b45464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E7=8E=89=E5=BD=AA?= <6575250+zhao-yubiao-code@user.noreply.gitee.com> Date: Thu, 4 Jan 2024 08:07:37 +0000 Subject: [PATCH] =?UTF-8?q?!53=20CVE-2023-38559=20=20=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=EF=BC=9Aghostscript=20=E4=B8=AD=E7=9A=84devn?= =?UTF-8?q?=5Fpcx=5Fwrite=5Frle()=20=E4=B8=AD=E7=9A=84=20base/gdevdevn.c:1?= =?UTF-8?q?973=20=E4=B8=AD=E5=AD=98=E5=9C=A8=E7=BC=93=E5=86=B2=E5=8C=BA?= =?UTF-8?q?=E6=BA=A2=E5=87=BA=E6=BC=8F=E6=B4=9E=EF=BC=8C=E5=85=81=E8=AE=B8?= =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E6=94=BB=E5=87=BB=E8=80=85=E9=80=9A=E8=BF=87?= =?UTF-8?q?=E7=B2=BE=E5=BF=83=E8=AE=BE=E8=AE=A1=E7=9A=84=20PDF=20=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=B9=B6=E4=BD=BF=E7=94=A8=20gs=20=E5=B0=86=E5=85=B6?= =?UTF-8?q?=E8=BE=93=E5=87=BA=E5=88=B0=20DEVN=20=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E6=9D=A5=E5=AF=BC=E8=87=B4=E6=8B=92=E7=BB=9D=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=20Merge=20pull=20request=20!53=20from=20MRTnight/openkylin/yan?= =?UTF-8?q?gtze?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/changelog | 1 - ...9-ghostscript-devn_pcx_write_rle-bas.patch | 291 ++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 debian/patches/0024-53-CVE-2023-38559-ghostscript-devn_pcx_write_rle-bas.patch diff --git a/debian/changelog b/debian/changelog index 15d5553..4198861 100644 --- a/debian/changelog +++ b/debian/changelog @@ -45,7 +45,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/debian/patches/0024-53-CVE-2023-38559-ghostscript-devn_pcx_write_rle-bas.patch b/debian/patches/0024-53-CVE-2023-38559-ghostscript-devn_pcx_write_rle-bas.patch new file mode 100644 index 0000000..9b32b38 --- /dev/null +++ b/debian/patches/0024-53-CVE-2023-38559-ghostscript-devn_pcx_write_rle-bas.patch @@ -0,0 +1,291 @@ +From: =?utf-8?b?6LW1546J5b2q?= + <6575250+zhao-yubiao-code@user.noreply.gitee.com> +Date: Thu, 4 Jan 2024 08:07:37 +0000 +Subject: =?utf-8?b?ITUzIENWRS0yMDIzLTM4NTU5ICDlronlhajmm7TmlrDvvJpnaG9zdHNj?= + =?utf-8?b?cmlwdCDkuK3nmoRkZXZuX3BjeF93cml0ZV9ybGUoKSDkuK3nmoQgYmFzZS9nZGV2?= + =?utf-8?b?ZGV2bi5jOjE5NzMg5Lit5a2Y5Zyo57yT5Yay5Yy65rqi5Ye65ryP5rSe77yM5YWB?= + =?utf-8?b?6K645pys5Zyw5pS75Ye76ICF6YCa6L+H57K+5b+D6K6+6K6h55qEIFBERiDmloc=?= + =?utf-8?b?5Lu25bm25L2/55SoIGdzIOWwhuWFtui+k+WHuuWIsCBERVZOIOiuvuWkh+adpQ==?= + =?utf-8?b?5a+86Ie05ouS57ud5pyN5YqhIE1lcmdlIHB1bGwgcmVxdWVzdCAhNTMgZnJvbSBN?= + =?utf-8?b?UlRuaWdodC9vcGVua3lsaW4veWFuZ3R6ZQ==?= + +--- + ...better-handling-of-error-during-PS-PDF-im.patch | 98 ++++++++++++++++++++++ + base/gdevdevn.c | 2 +- + contrib/gdevbjca.c | 36 ++++---- + devices/gdevlp8k.c | 5 +- + devices/vector/gdevxps.c | 43 +++++++--- + 5 files changed, 155 insertions(+), 29 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/base/gdevdevn.c b/base/gdevdevn.c +index d030561..7289e6b 100644 +--- a/base/gdevdevn.c ++++ b/base/gdevdevn.c +@@ -1913,7 +1913,7 @@ devn_pcx_write_rle(const byte * from, const byte * end, int step, gp_file * file + byte data = *from; + + from += step; +- if (data != *from || from == end) { ++ if (from >= end || data != *from) { + if (data >= 0xc0) + gp_fputc(0xc1, file); + } else { +diff --git a/contrib/gdevbjca.c b/contrib/gdevbjca.c +index a023f0e..3573f55 100644 +--- a/contrib/gdevbjca.c ++++ b/contrib/gdevbjca.c +@@ -342,12 +342,14 @@ bjc_compress(const byte *row, uint raster, byte *compressed) + register byte test, test2; + + test = *exam; +- while ( exam < end_row ) { +- test2 = *++exam; ++ while ( ++exam < end_row ) { ++ test2 = *exam; + if ( test == test2 ) + break; + test = test2; + } ++ /* exam points to the byte that didn't match, or end_row ++ * if we ran out of data. */ + + /* Find out how long the run is */ + end_dis = exam - 1; +@@ -655,12 +657,15 @@ FloydSteinbergDitheringC(gx_device_bjc_printer *dev, + for( i=width; i>0; i--, row+=4, err_vect+=3) { /*separate components */ + + /* C + K */ +- err_corrC = dev->bjc_gamma_tableC[ (*row) + (*(row+3))] +- + dev->FloydSteinbergC; +- err_corrM = dev->bjc_gamma_tableM[(*(row+1)) + (*(row+3))] +- + dev->FloydSteinbergM; +- err_corrY = dev->bjc_gamma_tableY[(*(row+2)) + (*(row+3))] +- + dev->FloydSteinbergY; ++ int v = row[0] + row[3]; ++ if (v > 255) v = 255; ++ err_corrC = dev->bjc_gamma_tableC[v] + dev->FloydSteinbergC; ++ v = row[1] + row[3]; ++ if (v > 255) v = 255; ++ err_corrM = dev->bjc_gamma_tableM[v] + dev->FloydSteinbergM; ++ v = row[2] + row[3]; ++ if (v > 255) v = 255; ++ err_corrY = dev->bjc_gamma_tableY[v] + dev->FloydSteinbergY; + + if(err_corrC > 4080 && limit_extr) err_corrC = 4080; + if(err_corrM > 4080 && limit_extr) err_corrM = 4080; +@@ -751,12 +756,15 @@ FloydSteinbergDitheringC(gx_device_bjc_printer *dev, + + for( i=width; i>0; i--, row-=4, err_vect-=3) { + +- err_corrC = dev->bjc_gamma_tableC[ (*row) + (*(row+3))] +- + dev->FloydSteinbergC; +- err_corrM = dev->bjc_gamma_tableM[(*(row+1)) + (*(row+3))] +- + dev->FloydSteinbergM; +- err_corrY = dev->bjc_gamma_tableY[(*(row+2)) + (*(row+3))] +- + dev->FloydSteinbergY; ++ int v = row[0] + row[3]; ++ if (v > 255) v = 255; ++ err_corrC = dev->bjc_gamma_tableC[v] + dev->FloydSteinbergC; ++ v = row[1] + row[3]; ++ if (v > 255) v = 255; ++ err_corrM = dev->bjc_gamma_tableM[v] + dev->FloydSteinbergM; ++ v = row[2] + row[3]; ++ if (v > 255) v = 255; ++ err_corrY = dev->bjc_gamma_tableY[v] + dev->FloydSteinbergY; + + if(err_corrC > 4080 && limit_extr) err_corrC = 4080; + if(err_corrM > 4080 && limit_extr) err_corrM = 4080; +diff --git a/devices/gdevlp8k.c b/devices/gdevlp8k.c +index 0a9bc03..55af94d 100644 +--- a/devices/gdevlp8k.c ++++ b/devices/gdevlp8k.c +@@ -185,7 +185,10 @@ lp8000_print_page(gx_device_printer *pdev, gp_file *prn_stream) + unsigned int report_size; + + byte *buf1 = (byte *)gs_malloc(pdev->memory, in_size, 1, "lp8000_print_page(buf1)"); +- byte *buf2 = (byte *)gs_malloc(pdev->memory, in_size, 1, "lp8000_print_page(buf2)"); ++ ++ /* Worst case for rle compression below is 3 bytes for each 2 bytes of ++ input, with extra final byte. */ ++ byte *buf2 = (byte *)gs_malloc(pdev->memory, in_size * 3 / 2 + 2, 1, "lp8000_print_page(buf2)"); + byte *in = buf1; + byte *out = buf2; + +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; ++} diff --git a/debian/patches/series b/debian/patches/series index 7e0ba9e..8bf8e3a 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -21,3 +21,4 @@ 0021-33-update-package-info.patch 0022-48-CVE-2020-21890-gdevclj.c-clj_media_size.patch 0023-40-CVE-2020-16304-base-gxicolor.c-image_render_color.patch +0024-53-CVE-2023-38559-ghostscript-devn_pcx_write_rle-bas.patch