!53 CVE-2023-38559 安全更新:ghostscript 中的devn_pcx_write_rle() 中的 base/gdevdevn.c:1973 中存在缓冲区溢出漏洞,允许本地攻击者通过精心设计的 PDF 文件并使用 gs 将其输出到 DEVN 设备来导致拒绝服务
Merge pull request !53 from MRTnight/openkylin/yangtze
This commit is contained in:
parent
73b0867528
commit
28e708a431
|
@ -45,7 +45,6 @@ ghostscript (9.50~dfsg-ok2) yangtze; urgency=medium
|
|||
-- wengz <wengzheng@bupt.edu.cn> Tue, 14 Mar 2023 15:42:43 +0800
|
||||
|
||||
ghostscript (9.50~dfsg-ok1) yangtze; urgency=medium
|
||||
|
||||
* Build for openKylin.
|
||||
|
||||
-- openKylinBot <openKylinBot@openkylin.com> Mon, 25 Apr 2022 22:03:04 +0800
|
||||
|
|
291
debian/patches/0024-53-CVE-2023-38559-ghostscript-devn_pcx_write_rle-bas.patch
vendored
Normal file
291
debian/patches/0024-53-CVE-2023-38559-ghostscript-devn_pcx_write_rle-bas.patch
vendored
Normal file
|
@ -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 <chris.liddell@artifex.com>
|
||||
+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<Path.Fill>\n");
|
||||
+ write_str_to_current_page(xps, "\t\t<ImageBrush ");
|
||||
+@@ -2214,17 +2222,6 @@ xps_image_end_image(gx_image_enum_common_t * info, bool draw_last)
|
||||
+ code = xps_add_image_relationship(pie);
|
||||
+
|
||||
+ exit:
|
||||
+- if (pie->pcs != 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<Path.Fill>\n");
|
||||
write_str_to_current_page(xps, "\t\t<ImageBrush ");
|
||||
@@ -2214,17 +2222,6 @@ xps_image_end_image(gx_image_enum_common_t * info, bool draw_last)
|
||||
code = xps_add_image_relationship(pie);
|
||||
|
||||
exit:
|
||||
- if (pie->pcs != 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;
|
||||
+}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue