Blame SOURCES/ghostscript-cve-2018-16540.patch

7c5933
From: Chris Liddell <chris.liddell@artifex.com>
7c5933
Date: Thu, 23 Aug 2018 13:13:25 +0000 (+0100)
7c5933
Subject: Bug 699661: Avoid sharing pointers between pdf14 compositors
7c5933
7c5933
Bug 699661: Avoid sharing pointers between pdf14 compositors
7c5933
7c5933
If a copdevice is triggered when the pdf14 compositor is the device, we make
7c5933
a copy of the device, then throw an error because, by default we're only allowed
7c5933
to copy the device prototype - then freeing it calls the finalize, which frees
7c5933
several pointers shared with the parent.
7c5933
7c5933
Make a pdf14 specific finish_copydevice() which NULLs the relevant pointers,
7c5933
before, possibly, throwing the same error as the default method.
7c5933
7c5933
This also highlighted a problem with reopening the X11 devices, where a custom
7c5933
error handler could be replaced with itself, meaning it also called itself,
7c5933
and infifite recursion resulted.
7c5933
7c5933
Keep a note of if the handler replacement has been done, and don't do it a
7c5933
second time.
7c5933
7c5933
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=c432131c3fdb2143e148e8ba88555f7f7a63b25e
7c5933
---
7c5933
7c5933
diff -up ghostscript-9.07/base/gdevp14.c.cve-2018-16540 ghostscript-9.07/base/gdevp14.c
7c5933
--- ghostscript-9.07/base/gdevp14.c.cve-2018-16540	2019-01-14 12:57:56.324331784 +0100
7c5933
+++ ghostscript-9.07/base/gdevp14.c	2019-01-14 13:00:38.224433442 +0100
7c5933
@@ -176,6 +176,7 @@ static	dev_proc_fill_mask(pdf14_fill_mas
7c5933
 static	dev_proc_stroke_path(pdf14_stroke_path);
7c5933
 static	dev_proc_begin_typed_image(pdf14_begin_typed_image);
7c5933
 static	dev_proc_text_begin(pdf14_text_begin);
7c5933
+static  dev_proc_finish_copydevice(pdf14_finish_copydevice);
7c5933
 static	dev_proc_create_compositor(pdf14_create_compositor);
7c5933
 static	dev_proc_create_compositor(pdf14_forward_create_compositor);
7c5933
 static	dev_proc_begin_transparency_group(pdf14_begin_transparency_group);
7c5933
@@ -246,7 +247,7 @@ static	const gx_color_map_procs *
7c5933
         pdf14_create_compositor,	/* create_compositor */\
7c5933
         NULL,				/* get_hardware_params */\
7c5933
         pdf14_text_begin,		/* text_begin */\
7c5933
-        NULL,				/* finish_copydevice */\
7c5933
+        pdf14_finish_copydevice,        /* finish_copydevice */\
7c5933
         pdf14_begin_transparency_group,\
7c5933
         pdf14_end_transparency_group,\
7c5933
         pdf14_begin_transparency_mask,\
7c5933
@@ -3217,6 +3218,19 @@ pdf14_text_begin(gx_device * dev, gs_ima
7c5933
     return code;
7c5933
 }
7c5933
 
7c5933
+static int
7c5933
+pdf14_finish_copydevice(gx_device *new_dev, const gx_device *from_dev)
7c5933
+{
7c5933
+    pdf14_device *pdev = (pdf14_device*)new_dev;
7c5933
+
7c5933
+    pdev->ctx = NULL;
7c5933
+    pdev->trans_group_parent_cmap_procs = NULL;
7c5933
+    pdev->smaskcolor = NULL;
7c5933
+
7c5933
+    /* Only allow copying the prototype. */
7c5933
+    return (from_dev->memory ? gs_note_error(gs_error_rangecheck) : 0);
7c5933
+}
7c5933
+
7c5933
 /*
7c5933
  * Implement copy_mono by filling lots of small rectangles.
7c5933
  */
7c5933
@@ -7499,6 +7513,7 @@ c_pdf14trans_clist_read_update(gs_compos
7c5933
                        before reopening the device */
7c5933
                     if (p14dev->ctx != NULL) {
7c5933
                         pdf14_ctx_free(p14dev->ctx);
7c5933
+                        p14dev->ctx = NULL;
7c5933
                     }
7c5933
                     dev_proc(tdev, open_device) (tdev);
7c5933
                 }
7c5933
diff -up ghostscript-9.07/base/gdevxini.c.cve-2018-16540 ghostscript-9.07/base/gdevxini.c
7c5933
--- ghostscript-9.07/base/gdevxini.c.cve-2018-16540	2019-01-14 13:01:43.310670279 +0100
7c5933
+++ ghostscript-9.07/base/gdevxini.c	2019-01-14 13:04:10.937939293 +0100
7c5933
@@ -59,7 +59,8 @@ static struct xv_ {
7c5933
     Boolean alloc_error;
7c5933
     XErrorHandler orighandler;
7c5933
     XErrorHandler oldhandler;
7c5933
-} x_error_handler;
7c5933
+    Boolean set;
7c5933
+} x_error_handler = {0};
7c5933
 
7c5933
 static int
7c5933
 x_catch_alloc(Display * dpy, XErrorEvent * err)
7c5933
@@ -74,7 +75,8 @@ x_catch_alloc(Display * dpy, XErrorEvent
7c5933
 int
7c5933
 x_catch_free_colors(Display * dpy, XErrorEvent * err)
7c5933
 {
7c5933
-    if (err->request_code == X_FreeColors)
7c5933
+    if (err->request_code == X_FreeColors ||
7c5933
+        x_error_handler.orighandler == x_catch_free_colors)
7c5933
         return 0;
7c5933
     return x_error_handler.orighandler(dpy, err);
7c5933
 }
7c5933
@@ -274,8 +276,10 @@ gdev_x_open(gx_device_X * xdev)
7c5933
         return_error(gs_error_ioerror);
7c5933
     }
7c5933
     /* Buggy X servers may cause a Bad Access on XFreeColors. */
7c5933
-    x_error_handler.orighandler = XSetErrorHandler(x_catch_free_colors);
7c5933
-
7c5933
+    if (!x_error_handler.set) {
7c5933
+        x_error_handler.orighandler = XSetErrorHandler(x_catch_free_colors);
7c5933
+        x_error_handler.set = True;
7c5933
+    }
7c5933
     /* Get X Resources.  Use the toolkit for this. */
7c5933
     XtToolkitInitialize();
7c5933
     app_con = XtCreateApplicationContext();