|
|
09061c |
From: Chris Liddell <chris.liddell@artifex.com>
|
|
|
09061c |
Date: Wed, 14 Nov 2018 09:50:08 +0000 (+0000)
|
|
|
09061c |
Subject: Bug 700176: check the *output* device for LockSafetyParams
|
|
|
09061c |
|
|
|
09061c |
Bug 700176: check the *output* device for LockSafetyParams
|
|
|
09061c |
|
|
|
09061c |
When calling .setdevice we were checking if LockSafetyParams was set, and if so
|
|
|
09061c |
throwing an invalidaccess error.
|
|
|
09061c |
|
|
|
09061c |
The problem is, if another device, for example the pdf14 compositor is the 'top'
|
|
|
09061c |
device, that does not (and cannot) honour LockSafetyParams.
|
|
|
09061c |
|
|
|
09061c |
To solve this, we'll now use the (relatively new) gxdso_current_output_device
|
|
|
09061c |
spec_op to retrieve the *actual* output device, and check the LockSafetyParams
|
|
|
09061c |
flag in that.
|
|
|
09061c |
|
|
|
09061c |
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=661e8d8fb8248c38d67958beda32f3a5876d0c3f
|
|
|
09061c |
|
|
|
09061c |
From: Chris Liddell <chris.liddell@artifex.com>
|
|
|
09061c |
Date: Wed, 14 Nov 2018 21:04:46 +0000 (+0000)
|
|
|
09061c |
Subject: Bug 700176: Use the actual output device for both devices in setdevice
|
|
|
09061c |
|
|
|
09061c |
Bug 700176: Use the actual output device for both devices in setdevice
|
|
|
09061c |
|
|
|
09061c |
Also fixes bug 700189.
|
|
|
09061c |
|
|
|
09061c |
The pdf14 compositor device, despite being a forwarding device, does not forward
|
|
|
09061c |
all spec_ops to it's target, only a select few are special cased for that.
|
|
|
09061c |
gxdso_current_output_device needs to be included in those special cases.
|
|
|
09061c |
|
|
|
09061c |
The original commit (661e8d8fb8248) changed the code to use the spec_op to
|
|
|
09061c |
retrieve the output device, checking that for LockSafetyParams. If
|
|
|
09061c |
LockSafetyParams is set, it returns an invalidaccess error if the new device
|
|
|
09061c |
differs from the current device.
|
|
|
09061c |
|
|
|
09061c |
When we do the comparison between the two devices, we need to check the
|
|
|
09061c |
output device in both cases.
|
|
|
09061c |
|
|
|
09061c |
This is complicated by the fact that the new device may not have ever been set
|
|
|
09061c |
(and thus fully initialised), and may not have a spec_op method available at
|
|
|
09061c |
that point.
|
|
|
09061c |
|
|
|
09061c |
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=ea1b3ef437f39e45874f821c06bd953196625ac5
|
|
|
09061c |
|
|
|
09061c |
From: Chris Liddell <chris.liddell@artifex.com>
|
|
|
09061c |
Date: Mon, 17 Sep 2018 13:06:12 +0000 (+0100)
|
|
|
09061c |
Subject: Implement .currentoutputdevice operator
|
|
|
09061c |
|
|
|
09061c |
Implement .currentoutputdevice operator
|
|
|
09061c |
|
|
|
09061c |
The currentdevice operator returns the device currently installed in the
|
|
|
09061c |
graphics state. This can be the output/page device, but also could be a
|
|
|
09061c |
forwarding device (bbox device), compositor (pdf14) or subclass device
|
|
|
09061c |
(erasepage optimisation, First/Last page etc).
|
|
|
09061c |
|
|
|
09061c |
In certain circumstances (for example during a setpagedevice) we want to be
|
|
|
09061c |
sure we're retrieving the *actual* output/page device.
|
|
|
09061c |
|
|
|
09061c |
The new .currentoutputdevice operator uses the spec_op device method to traverse
|
|
|
09061c |
any chain of devices and retrieve the final device in the chain, which
|
|
|
09061c |
should always be the output/page device.
|
|
|
09061c |
|
|
|
09061c |
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=7c3e7eee829cc3d2582e4aa7ae1fd495ca72cef1
|
|
|
09061c |
|
|
|
09061c |
From: Ken Sharp <ken.sharp@artifex.com>
|
|
|
09061c |
Date: Mon, 19 Nov 2018 09:00:54 +0000 (+0000)
|
|
|
09061c |
Subject: Coverity ID 327264 - move pointer NULL check
|
|
|
09061c |
|
|
|
09061c |
Coverity ID 327264 - move pointer NULL check
|
|
|
09061c |
|
|
|
09061c |
Due to recent changes in this code, the pointer was being dereferenced
|
|
|
09061c |
before we checked it to see if it was NULL. Moe the check so that we
|
|
|
09061c |
check for NULL before dereferencing.
|
|
|
09061c |
|
|
|
09061c |
The 'pvalue' of the operand can be NULL, even if the object is a t_device
|
|
|
09061c |
type, because invalidate_stack_devices traverses the operand stack
|
|
|
09061c |
looking for devices, and sets their pvalue member to NULL in order to
|
|
|
09061c |
invalidate them so that they cannot be used.
|
|
|
09061c |
|
|
|
09061c |
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=a4228a0d8d657fca3bb3becb93a43fae061beae8
|
|
|
09061c |
---
|
|
|
09061c |
|
|
|
09061c |
diff -up ghostscript-9.07/base/gdevdflt.c.cve-2018-19409 ghostscript-9.07/base/gdevdflt.c
|
|
|
09061c |
--- ghostscript-9.07/base/gdevdflt.c.cve-2018-19409 2013-02-14 08:58:13.000000000 +0100
|
|
|
09061c |
+++ ghostscript-9.07/base/gdevdflt.c 2018-11-29 12:42:59.882160045 +0100
|
|
|
09061c |
@@ -954,6 +954,11 @@ gx_default_dev_spec_op(gx_device *pdev,
|
|
|
09061c |
return 4;
|
|
|
09061c |
}
|
|
|
09061c |
return 0; /* Otherwise no change */
|
|
|
09061c |
+ case gxdso_current_output_device:
|
|
|
09061c |
+ {
|
|
|
09061c |
+ *(gx_device **)data = pdev;
|
|
|
09061c |
+ return 0;
|
|
|
09061c |
+ }
|
|
|
09061c |
}
|
|
|
09061c |
return gs_error_undefined;
|
|
|
09061c |
}
|
|
|
09061c |
diff -up ghostscript-9.07/base/gdevp14.c.cve-2018-19409 ghostscript-9.07/base/gdevp14.c
|
|
|
09061c |
--- ghostscript-9.07/base/gdevp14.c.cve-2018-19409 2018-11-29 12:42:59.784161429 +0100
|
|
|
09061c |
+++ ghostscript-9.07/base/gdevp14.c 2018-11-29 13:15:49.265339432 +0100
|
|
|
09061c |
@@ -5089,6 +5089,11 @@ pdf14_dev_spec_op(gx_device *pdev, int d
|
|
|
09061c |
return 0;
|
|
|
09061c |
}
|
|
|
09061c |
}
|
|
|
09061c |
+ if (dev_spec_op == gxdso_current_output_device) {
|
|
|
09061c |
+ gx_device * target = ((gx_device_forward *)pdev)->target;
|
|
|
09061c |
+ return dev_proc(target, dev_spec_op)(target, dev_spec_op, data, size);
|
|
|
09061c |
+ }
|
|
|
09061c |
+
|
|
|
09061c |
return gx_default_dev_spec_op(pdev, dev_spec_op, data, size);
|
|
|
09061c |
}
|
|
|
09061c |
|
|
|
09061c |
diff -up ghostscript-9.07/base/gxdevsop.h.cve-2018-19409 ghostscript-9.07/base/gxdevsop.h
|
|
|
09061c |
--- ghostscript-9.07/base/gxdevsop.h.cve-2018-19409 2013-02-14 08:58:13.000000000 +0100
|
|
|
09061c |
+++ ghostscript-9.07/base/gxdevsop.h 2018-11-29 12:42:59.884160017 +0100
|
|
|
09061c |
@@ -253,6 +253,10 @@ enum {
|
|
|
09061c |
* Return 0 for 'no special treatment', or 1 for the anitdropout
|
|
|
09061c |
* downscaler. */
|
|
|
09061c |
gxdso_interpolate_antidropout,
|
|
|
09061c |
+ /* Retrieve the last device in a device chain
|
|
|
09061c |
+ (either forwarding or subclass devices).
|
|
|
09061c |
+ */
|
|
|
09061c |
+ gxdso_current_output_device,
|
|
|
09061c |
/* Add new gxdso_ keys above this. */
|
|
|
09061c |
gxdso_pattern__LAST
|
|
|
09061c |
};
|
|
|
09061c |
diff -up ghostscript-9.07/psi/zdevice.c.cve-2018-19409 ghostscript-9.07/psi/zdevice.c
|
|
|
09061c |
--- ghostscript-9.07/psi/zdevice.c.cve-2018-19409 2013-02-14 08:58:13.000000000 +0100
|
|
|
09061c |
+++ ghostscript-9.07/psi/zdevice.c 2018-11-29 12:42:59.884160017 +0100
|
|
|
09061c |
@@ -34,6 +34,7 @@
|
|
|
09061c |
#include "gxgetbit.h"
|
|
|
09061c |
#include "store.h"
|
|
|
09061c |
#include "gsicc_manage.h"
|
|
|
09061c |
+#include "gxdevsop.h"
|
|
|
09061c |
|
|
|
09061c |
/* <device> <keep_open> .copydevice2 <newdevice> */
|
|
|
09061c |
static int
|
|
|
09061c |
@@ -56,6 +57,7 @@ zcopydevice2(i_ctx_t *i_ctx_p)
|
|
|
09061c |
}
|
|
|
09061c |
|
|
|
09061c |
/* - currentdevice <device> */
|
|
|
09061c |
+/* Returns the current device in the graphics state */
|
|
|
09061c |
int
|
|
|
09061c |
zcurrentdevice(i_ctx_t *i_ctx_p)
|
|
|
09061c |
{
|
|
|
09061c |
@@ -70,6 +72,34 @@ zcurrentdevice(i_ctx_t *i_ctx_p)
|
|
|
09061c |
return 0;
|
|
|
09061c |
}
|
|
|
09061c |
|
|
|
09061c |
+/* - .currentoutputdevice <device> */
|
|
|
09061c |
+/* Returns the *output* device - which will often
|
|
|
09061c |
+ be the same as above, but not always: if a compositor
|
|
|
09061c |
+ or other forwarding device, or subclassing device is
|
|
|
09061c |
+ in force, that will be referenced by the graphics state
|
|
|
09061c |
+ rather than the output device.
|
|
|
09061c |
+ This is equivalent of currentdevice device, but returns
|
|
|
09061c |
+ the *device* object, rather than the dictionary describing
|
|
|
09061c |
+ the device and device state.
|
|
|
09061c |
+ */
|
|
|
09061c |
+static int
|
|
|
09061c |
+zcurrentoutputdevice(i_ctx_t *i_ctx_p)
|
|
|
09061c |
+{
|
|
|
09061c |
+ os_ptr op = osp;
|
|
|
09061c |
+ gx_device *odev = NULL, *dev = gs_currentdevice(igs);
|
|
|
09061c |
+ gs_ref_memory_t *mem = (gs_ref_memory_t *) dev->memory;
|
|
|
09061c |
+ int code = dev_proc(dev, dev_spec_op)(dev,
|
|
|
09061c |
+ gxdso_current_output_device, (void *)&odev, 0);
|
|
|
09061c |
+ if (code < 0)
|
|
|
09061c |
+ return code;
|
|
|
09061c |
+
|
|
|
09061c |
+ push(1);
|
|
|
09061c |
+ make_tav(op, t_device,
|
|
|
09061c |
+ (mem == 0 ? avm_foreign : imemory_space(mem)) | a_all,
|
|
|
09061c |
+ pdevice, odev);
|
|
|
09061c |
+ return 0;
|
|
|
09061c |
+}
|
|
|
09061c |
+
|
|
|
09061c |
/* <device> .devicename <string> */
|
|
|
09061c |
static int
|
|
|
09061c |
zdevicename(i_ctx_t *i_ctx_p)
|
|
|
09061c |
@@ -450,13 +480,34 @@ zputdeviceparams(i_ctx_t *i_ctx_p)
|
|
|
09061c |
int
|
|
|
09061c |
zsetdevice(i_ctx_t *i_ctx_p)
|
|
|
09061c |
{
|
|
|
09061c |
- gx_device *dev = gs_currentdevice(igs);
|
|
|
09061c |
+ gx_device *odev = NULL, *dev = gs_currentdevice(igs);
|
|
|
09061c |
+ gx_device *ndev = NULL;
|
|
|
09061c |
os_ptr op = osp;
|
|
|
09061c |
- int code = 0;
|
|
|
09061c |
+ int code = dev_proc(dev, dev_spec_op)(dev,
|
|
|
09061c |
+ gxdso_current_output_device, (void *)&odev, 0);
|
|
|
09061c |
|
|
|
09061c |
+ if (code < 0)
|
|
|
09061c |
+ return code;
|
|
|
09061c |
check_write_type(*op, t_device);
|
|
|
09061c |
- if (dev->LockSafetyParams) { /* do additional checking if locked */
|
|
|
09061c |
- if(op->value.pdevice != dev) /* don't allow a different device */
|
|
|
09061c |
+
|
|
|
09061c |
+ if (op->value.pdevice == 0)
|
|
|
09061c |
+ return gs_note_error(gs_error_undefined);
|
|
|
09061c |
+
|
|
|
09061c |
+ /* slightly icky special case: the new device may not have had
|
|
|
09061c |
+ * it's procs initialised, at this point - but we need to check
|
|
|
09061c |
+ * whether we're being asked to change the device here
|
|
|
09061c |
+ */
|
|
|
09061c |
+ if (dev_proc((op->value.pdevice), dev_spec_op) == NULL)
|
|
|
09061c |
+ ndev = op->value.pdevice;
|
|
|
09061c |
+ else
|
|
|
09061c |
+ code = dev_proc((op->value.pdevice), dev_spec_op)(op->value.pdevice,
|
|
|
09061c |
+ gxdso_current_output_device, (void *)&ndev, 0);
|
|
|
09061c |
+
|
|
|
09061c |
+ if (code < 0)
|
|
|
09061c |
+ return code;
|
|
|
09061c |
+
|
|
|
09061c |
+ if (odev->LockSafetyParams) { /* do additional checking if locked */
|
|
|
09061c |
+ if(ndev != odev) /* don't allow a different device */
|
|
|
09061c |
return_error(e_invalidaccess);
|
|
|
09061c |
}
|
|
|
09061c |
#ifndef PSI_INCLUDED
|
|
|
09061c |
@@ -480,6 +531,7 @@ const op_def zdevice_op_defs[] =
|
|
|
09061c |
{
|
|
|
09061c |
{"1.copydevice2", zcopydevice2},
|
|
|
09061c |
{"0currentdevice", zcurrentdevice},
|
|
|
09061c |
+ {"0.currentoutputdevice", zcurrentoutputdevice},
|
|
|
09061c |
{"1.devicename", zdevicename},
|
|
|
09061c |
{"0.doneshowpage", zdoneshowpage},
|
|
|
09061c |
{"0flushpage", zflushpage},
|
|
|
09061c |
diff -up ghostscript-9.07/Resource/Init/gs_init.ps.cve-2018-19409 ghostscript-9.07/Resource/Init/gs_init.ps
|
|
|
09061c |
--- ghostscript-9.07/Resource/Init/gs_init.ps.cve-2018-19409 2018-11-29 12:42:59.873160172 +0100
|
|
|
09061c |
+++ ghostscript-9.07/Resource/Init/gs_init.ps 2018-11-29 12:42:59.884160017 +0100
|
|
|
09061c |
@@ -2160,7 +2160,7 @@ SAFER { .setsafe } if
|
|
|
09061c |
/.shfill /.argindex /.bytestring /.namestring /.stringbreak /.stringmatch /.globalvmarray /.globalvmdict /.globalvmpackedarray /.globalvmstring
|
|
|
09061c |
/.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
|
|
|
09061c |
/.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
|
|
|
09061c |
-/.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath
|
|
|
09061c |
+/.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice
|
|
|
09061c |
|
|
|
09061c |
% Used by a free user in the Library of Congress. Apparently this is used to
|
|
|
09061c |
% draw a partial page, which is then filled in by the results of a barcode
|
|
|
09061c |
diff -up ghostscript-9.07/Resource/Init/gs_setpd.ps.cve-2018-19409 ghostscript-9.07/Resource/Init/gs_setpd.ps
|
|
|
09061c |
--- ghostscript-9.07/Resource/Init/gs_setpd.ps.cve-2018-19409 2018-11-29 12:42:59.880160073 +0100
|
|
|
09061c |
+++ ghostscript-9.07/Resource/Init/gs_setpd.ps 2018-11-29 12:42:59.885160002 +0100
|
|
|
09061c |
@@ -772,7 +772,13 @@ SETPDDEBUG { (Selecting.) = pstack flush
|
|
|
09061c |
% Stack: mark <orig> <request> <merged> <failed>
|
|
|
09061c |
SETPDDEBUG { (Constructing.) = pstack flush } if
|
|
|
09061c |
|
|
|
09061c |
- currentdevice .devicename 2 index /OutputDevice get eq
|
|
|
09061c |
+ % Non-obvious: we need to check the name of the output device, to tell
|
|
|
09061c |
+ % whether we're going to have to replace the entire device chain (which
|
|
|
09061c |
+ % may be only one device, or may be multiple devices.
|
|
|
09061c |
+ % If we're not replacing the entire change, we have to use the device in
|
|
|
09061c |
+ % the graphics state, so the configuration of the entire device chain is
|
|
|
09061c |
+ % correctly set.
|
|
|
09061c |
+ .currentoutputdevice .devicename 2 index /OutputDevice get eq
|
|
|
09061c |
{ currentdevice }
|
|
|
09061c |
{ 1 index /OutputDevice get finddevice }
|
|
|
09061c |
ifelse
|