!42 CVE-2020-16303 Artifex Software Ghostscript v9.50版本中的devices/vector/gdevxps.c文件的xps_finish_image_path()存在资源管理错误漏洞
Merge pull request !42 from Uaenasxbpy/openkylin/yangtze
This commit is contained in:
commit
1313069fd7
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue