gnu: ghostscript: Update to 9.26.
* gnu/packages/patches/ghostscript-bug-699708.patch, gnu/packages/patches/ghostscript-CVE-2018-16509.patch: Delete files. * gnu/local.mk (dist_patch_DATA): Remove them. * gnu/packages/ghostscript.scm (ghostscript): Update to 9.26. [source](patches): Remove obsolete.master
parent
30eb854a57
commit
87f29c1e5d
|
@ -738,8 +738,6 @@ dist_patch_DATA = \
|
|||
%D%/packages/patches/ghc-8.0-fall-back-to-madv_dontneed.patch \
|
||||
%D%/packages/patches/ghc-dont-pass-linker-flags-via-response-files.patch \
|
||||
%D%/packages/patches/ghc-haddock-library-unbundle.patch \
|
||||
%D%/packages/patches/ghostscript-CVE-2018-16509.patch \
|
||||
%D%/packages/patches/ghostscript-bug-699708.patch \
|
||||
%D%/packages/patches/ghostscript-no-header-id.patch \
|
||||
%D%/packages/patches/ghostscript-no-header-uuid.patch \
|
||||
%D%/packages/patches/ghostscript-no-header-creationdate.patch \
|
||||
|
|
|
@ -135,7 +135,7 @@ printing, and psresize, for adjusting page sizes.")
|
|||
(define-public ghostscript
|
||||
(package
|
||||
(name "ghostscript")
|
||||
(version "9.24")
|
||||
(version "9.26")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
|
@ -145,10 +145,8 @@ printing, and psresize, for adjusting page sizes.")
|
|||
"/ghostscript-" version ".tar.xz"))
|
||||
(sha256
|
||||
(base32
|
||||
"1mk922rnml93w2g42yxiyn8xqanc50cm65irrgh0b6lp4kgifjfl"))
|
||||
(patches (search-patches "ghostscript-CVE-2018-16509.patch"
|
||||
"ghostscript-bug-699708.patch"
|
||||
"ghostscript-no-header-creationdate.patch"
|
||||
"1645f47all5w27bfhiq15vycdm954lmr6agqkrp68ksq6xglgvch"))
|
||||
(patches (search-patches "ghostscript-no-header-creationdate.patch"
|
||||
"ghostscript-no-header-id.patch"
|
||||
"ghostscript-no-header-uuid.patch"))
|
||||
(modules '((guix build utils)))
|
||||
|
|
|
@ -1,193 +0,0 @@
|
|||
Ghostscript 9.24 was released with an incomplete fix for CVE-2018-16509:
|
||||
https://nvd.nist.gov/vuln/detail/CVE-2018-16509
|
||||
https://bugs.chromium.org/p/project-zero/issues/detail?id=1640#c19
|
||||
https://bugs.ghostscript.com/show_bug.cgi?id=699718
|
||||
|
||||
The reproducers no longer work after applying these commits:
|
||||
|
||||
https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=5812b1b78fc4d36fdc293b7859de69241140d590
|
||||
https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=e914f1da46e33decc534486598dc3eadf69e6efb
|
||||
https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=3e5d316b72e3965b7968bb1d96baa137cd063ac6
|
||||
https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=643b24dbd002fb9c131313253c307cf3951b3d47
|
||||
|
||||
This patch is a "squashed" version of those.
|
||||
|
||||
diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps
|
||||
index bba3c8c0e..8fa7c51df 100644
|
||||
--- a/Resource/Init/gs_setpd.ps
|
||||
+++ b/Resource/Init/gs_setpd.ps
|
||||
@@ -95,27 +95,41 @@ level2dict begin
|
||||
{ % Since setpagedevice doesn't create new device objects,
|
||||
% we must (carefully) reinstall the old parameters in
|
||||
% the same device.
|
||||
- .currentpagedevice pop //null currentdevice //null .trysetparams
|
||||
+ .currentpagedevice pop //null currentdevice //null
|
||||
+ { .trysetparams } .internalstopped
|
||||
+ {
|
||||
+ //null
|
||||
+ } if
|
||||
dup type /booleantype eq
|
||||
{ pop pop }
|
||||
- { % This should never happen!
|
||||
+ {
|
||||
SETPDDEBUG { (Error in .trysetparams!) = pstack flush } if
|
||||
- cleartomark pop pop pop
|
||||
+ {cleartomark pop pop pop} .internalstopped pop
|
||||
+ % if resetting the entire device state failed, at least put back the
|
||||
+ % security related key
|
||||
+ currentdevice //null //false mark /.LockSafetyParams
|
||||
+ currentpagedevice /.LockSafetyParams .knownget not
|
||||
+ {systemdict /SAFER .knownget not {//false} } if
|
||||
+ .putdeviceparamsonly
|
||||
/.installpagedevice cvx /rangecheck signalerror
|
||||
}
|
||||
ifelse pop pop
|
||||
% A careful reading of the Red Book reveals that an erasepage
|
||||
% should occur, but *not* an initgraphics.
|
||||
erasepage .beginpage
|
||||
- } bind def
|
||||
+ } bind executeonly def
|
||||
|
||||
/.uninstallpagedevice
|
||||
- { 2 .endpage { .currentnumcopies //false .outputpage } if
|
||||
+ {
|
||||
+ {2 .endpage { .currentnumcopies //false .outputpage } if} .internalstopped pop
|
||||
nulldevice
|
||||
} bind def
|
||||
|
||||
(%grestorepagedevice) cvn
|
||||
- { .uninstallpagedevice grestore .installpagedevice
|
||||
+ {
|
||||
+ .uninstallpagedevice
|
||||
+ grestore
|
||||
+ .installpagedevice
|
||||
} bind def
|
||||
|
||||
(%grestoreallpagedevice) cvn
|
||||
diff --git a/psi/zdevice2.c b/psi/zdevice2.c
|
||||
index 0c7080d57..159a0c0d9 100644
|
||||
--- a/psi/zdevice2.c
|
||||
+++ b/psi/zdevice2.c
|
||||
@@ -251,8 +251,8 @@ z2currentgstate(i_ctx_t *i_ctx_p)
|
||||
/* ------ Wrappers for operators that reset the graphics state. ------ */
|
||||
|
||||
/* Check whether we need to call out to restore the page device. */
|
||||
-static bool
|
||||
-restore_page_device(const gs_gstate * pgs_old, const gs_gstate * pgs_new)
|
||||
+static int
|
||||
+restore_page_device(i_ctx_t *i_ctx_p, const gs_gstate * pgs_old, const gs_gstate * pgs_new)
|
||||
{
|
||||
gx_device *dev_old = gs_currentdevice(pgs_old);
|
||||
gx_device *dev_new;
|
||||
@@ -260,9 +260,10 @@ restore_page_device(const gs_gstate * pgs_old, const gs_gstate * pgs_new)
|
||||
gx_device *dev_t2;
|
||||
bool samepagedevice = obj_eq(dev_old->memory, &gs_int_gstate(pgs_old)->pagedevice,
|
||||
&gs_int_gstate(pgs_new)->pagedevice);
|
||||
+ bool LockSafetyParams = dev_old->LockSafetyParams;
|
||||
|
||||
if ((dev_t1 = (*dev_proc(dev_old, get_page_device)) (dev_old)) == 0)
|
||||
- return false;
|
||||
+ return 0;
|
||||
/* If we are going to putdeviceparams in a callout, we need to */
|
||||
/* unlock temporarily. The device will be re-locked as needed */
|
||||
/* by putdeviceparams from the pgs_old->pagedevice dict state. */
|
||||
@@ -271,23 +272,51 @@ restore_page_device(const gs_gstate * pgs_old, const gs_gstate * pgs_new)
|
||||
dev_new = gs_currentdevice(pgs_new);
|
||||
if (dev_old != dev_new) {
|
||||
if ((dev_t2 = (*dev_proc(dev_new, get_page_device)) (dev_new)) == 0)
|
||||
- return false;
|
||||
- if (dev_t1 != dev_t2)
|
||||
- return true;
|
||||
+ samepagedevice = true;
|
||||
+ else if (dev_t1 != dev_t2)
|
||||
+ samepagedevice = false;
|
||||
+ }
|
||||
+
|
||||
+ if (LockSafetyParams && !samepagedevice) {
|
||||
+ const int required_ops = 512;
|
||||
+ const int required_es = 32;
|
||||
+
|
||||
+ /* The %grestorepagedevice must complete: the biggest danger
|
||||
+ is operand stack overflow. As we use get/putdeviceparams
|
||||
+ that means pushing all the device params onto the stack,
|
||||
+ pdfwrite having by far the largest number of parameters
|
||||
+ at (currently) 212 key/value pairs - thus needing (currently)
|
||||
+ 424 entries on the op stack. Allowing for working stack
|
||||
+ space, and safety margin.....
|
||||
+ */
|
||||
+ if (required_ops + ref_stack_count(&o_stack) >= ref_stack_max_count(&o_stack)) {
|
||||
+ gs_currentdevice(pgs_old)->LockSafetyParams = LockSafetyParams;
|
||||
+ return_error(gs_error_stackoverflow);
|
||||
+ }
|
||||
+ /* We also want enough exec stack space - 32 is an overestimate of
|
||||
+ what we need to complete the Postscript call out.
|
||||
+ */
|
||||
+ if (required_es + ref_stack_count(&e_stack) >= ref_stack_max_count(&e_stack)) {
|
||||
+ gs_currentdevice(pgs_old)->LockSafetyParams = LockSafetyParams;
|
||||
+ return_error(gs_error_execstackoverflow);
|
||||
+ }
|
||||
}
|
||||
/*
|
||||
* The current implementation of setpagedevice just sets new
|
||||
* parameters in the same device object, so we have to check
|
||||
* whether the page device dictionaries are the same.
|
||||
*/
|
||||
- return !samepagedevice;
|
||||
+ return samepagedevice ? 0 : 1;
|
||||
}
|
||||
|
||||
/* - grestore - */
|
||||
static int
|
||||
z2grestore(i_ctx_t *i_ctx_p)
|
||||
{
|
||||
- if (!restore_page_device(igs, gs_gstate_saved(igs)))
|
||||
+ int code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs));
|
||||
+ if (code < 0) return code;
|
||||
+
|
||||
+ if (code == 0)
|
||||
return gs_grestore(igs);
|
||||
return push_callout(i_ctx_p, "%grestorepagedevice");
|
||||
}
|
||||
@@ -297,7 +326,9 @@ static int
|
||||
z2grestoreall(i_ctx_t *i_ctx_p)
|
||||
{
|
||||
for (;;) {
|
||||
- if (!restore_page_device(igs, gs_gstate_saved(igs))) {
|
||||
+ int code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs));
|
||||
+ if (code < 0) return code;
|
||||
+ if (code == 0) {
|
||||
bool done = !gs_gstate_saved(gs_gstate_saved(igs));
|
||||
|
||||
gs_grestore(igs);
|
||||
@@ -328,11 +359,15 @@ z2restore(i_ctx_t *i_ctx_p)
|
||||
if (code < 0) return code;
|
||||
|
||||
while (gs_gstate_saved(gs_gstate_saved(igs))) {
|
||||
- if (restore_page_device(igs, gs_gstate_saved(igs)))
|
||||
+ code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs));
|
||||
+ if (code < 0) return code;
|
||||
+ if (code > 0)
|
||||
return push_callout(i_ctx_p, "%restore1pagedevice");
|
||||
gs_grestore(igs);
|
||||
}
|
||||
- if (restore_page_device(igs, gs_gstate_saved(igs)))
|
||||
+ code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs));
|
||||
+ if (code < 0) return code;
|
||||
+ if (code > 0)
|
||||
return push_callout(i_ctx_p, "%restorepagedevice");
|
||||
|
||||
code = dorestore(i_ctx_p, asave);
|
||||
@@ -355,9 +390,12 @@ static int
|
||||
z2setgstate(i_ctx_t *i_ctx_p)
|
||||
{
|
||||
os_ptr op = osp;
|
||||
+ int code;
|
||||
|
||||
check_stype(*op, st_igstate_obj);
|
||||
- if (!restore_page_device(igs, igstate_ptr(op)))
|
||||
+ code = restore_page_device(i_ctx_p, igs, igstate_ptr(op));
|
||||
+ if (code < 0) return code;
|
||||
+ if (code == 0)
|
||||
return zsetgstate(i_ctx_p);
|
||||
return push_callout(i_ctx_p, "%setgstatepagedevice");
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
Additional security fix that missed 9.24.
|
||||
|
||||
Taken from upstream:
|
||||
http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=fb713b3818b52d8a6cf62c951eba2e1795ff9624
|
||||
|
||||
From fb713b3818b52d8a6cf62c951eba2e1795ff9624 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Liddell <chris.liddell@artifex.com>
|
||||
Date: Thu, 6 Sep 2018 09:16:22 +0100
|
||||
Subject: [PATCH] Bug 699708 (part 1): 'Hide' non-replaceable error handlers
|
||||
for SAFER
|
||||
|
||||
We already had a 'private' dictionary for non-standard errors: gserrordict.
|
||||
|
||||
This now includes all the default error handlers, the dictionary is made
|
||||
noaccess and all the prodedures are bound and executeonly.
|
||||
|
||||
When running with -dSAFER, in the event of a Postscript error, instead of
|
||||
pulling the handler from errordict, we'll pull it from gserrordict - thus
|
||||
malicious input cannot trigger problems by the use of custom error handlers.
|
||||
|
||||
errordict remains open and writeable, so files such as the Quality Logic tests
|
||||
that install their own handlers will still 'work', with the exception that the
|
||||
custom error handlers will not be called.
|
||||
|
||||
This is a 'first pass', 'sledgehammer' approach: a nice addition would to allow
|
||||
an integrator to specify a list of errors that are not to be replaced (for
|
||||
example, embedded applications would probably want to ensure that VMerror is
|
||||
always handled as they intend).
|
||||
---
|
||||
Resource/Init/gs_init.ps | 29 ++++++++++++++++++-----------
|
||||
psi/interp.c | 30 +++++++++++++++++++++---------
|
||||
2 files changed, 39 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
|
||||
index 071c39205..bc8b7951c 100644
|
||||
--- a/Resource/Init/gs_init.ps
|
||||
+++ b/Resource/Init/gs_init.ps
|
||||
@@ -881,7 +881,7 @@ userdict /.currentresourcefile //null put
|
||||
{ not exch pop exit } { pop } ifelse
|
||||
}
|
||||
for exch pop .quit
|
||||
- } bind def
|
||||
+ } bind executeonly def
|
||||
/.errorhandler % <command> <errorname> .errorhandler -
|
||||
{ % Detect an internal 'stopped'.
|
||||
1 .instopped { //null eq { pop pop stop } if } if
|
||||
@@ -926,7 +926,7 @@ userdict /.currentresourcefile //null put
|
||||
$error /globalmode get $error /.nosetlocal get and .setglobal
|
||||
$error /.inerror //false put
|
||||
stop
|
||||
- } bind def
|
||||
+ } bind executeonly def
|
||||
% Define the standard handleerror. We break out the printing procedure
|
||||
% (.printerror) so that it can be extended for binary output
|
||||
% if the Level 2 facilities are present.
|
||||
@@ -976,7 +976,7 @@ userdict /.currentresourcefile //null put
|
||||
ifelse % newerror
|
||||
end
|
||||
flush
|
||||
- } bind def
|
||||
+ } bind executeonly def
|
||||
/.printerror_long % long error printout,
|
||||
% $error is on the dict stack
|
||||
{ % Push the (anonymous) stack printing procedure.
|
||||
@@ -1053,14 +1053,14 @@ userdict /.currentresourcefile //null put
|
||||
{ (Current file position is ) print position = }
|
||||
if
|
||||
|
||||
- } bind def
|
||||
+ } bind executeonly def
|
||||
% Define a procedure for clearing the error indication.
|
||||
/.clearerror
|
||||
{ $error /newerror //false put
|
||||
$error /errorname //null put
|
||||
$error /errorinfo //null put
|
||||
0 .setoserrno
|
||||
- } bind def
|
||||
+ } bind executeonly def
|
||||
|
||||
% Define $error. This must be in local VM.
|
||||
.currentglobal //false .setglobal
|
||||
@@ -1086,11 +1086,15 @@ end
|
||||
/errordict ErrorNames length 3 add dict
|
||||
.forcedef % errordict is local, systemdict is global
|
||||
.setglobal % back to global VM
|
||||
-% For greater Adobe compatibility, we put all non-standard errors in a
|
||||
-% separate dictionary, gserrordict. It does not need to be in local VM,
|
||||
-% because PostScript programs do not access it.
|
||||
+% gserrordict contains all the default error handling methods, but unlike
|
||||
+% errordict it is noaccess after creation (also it is in global VM).
|
||||
+% When running 'SAFER', we'll ignore the contents of errordict, which
|
||||
+% may have been tampered with by the running job, and always use gserrordict
|
||||
+% gserrordict also contains any non-standard errors, for better compatibility
|
||||
+% with Adobe.
|
||||
+%
|
||||
% NOTE: the name gserrordict is known to the interpreter.
|
||||
-/gserrordict 5 dict def
|
||||
+/gserrordict ErrorNames length 3 add dict def
|
||||
% Register an error in errordict. We make this a procedure because we only
|
||||
% register the Level 1 errors here: the rest are registered by "feature"
|
||||
% files. However, ErrorNames contains all of the error names regardless of
|
||||
@@ -1119,8 +1123,11 @@ errordict begin
|
||||
} bind def
|
||||
end % errordict
|
||||
|
||||
-% Put non-standard errors in gserrordict.
|
||||
-gserrordict /unknownerror errordict /unknownerror get put
|
||||
+% Put all the default handlers in gserrordict
|
||||
+gserrordict
|
||||
+errordict {2 index 3 1 roll put} forall
|
||||
+noaccess pop
|
||||
+% remove the non-standard errors from errordict
|
||||
errordict /unknownerror .undef
|
||||
% Define a stable private copy of handleerror that we will always use under
|
||||
% JOBSERVER mode.
|
||||
diff --git a/psi/interp.c b/psi/interp.c
|
||||
index c27b70dca..d41a9d3f5 100644
|
||||
--- a/psi/interp.c
|
||||
+++ b/psi/interp.c
|
||||
@@ -661,16 +661,28 @@ again:
|
||||
return code;
|
||||
if (gs_errorname(i_ctx_p, code, &error_name) < 0)
|
||||
return code; /* out-of-range error code! */
|
||||
- /*
|
||||
- * For greater Adobe compatibility, only the standard PostScript errors
|
||||
- * are defined in errordict; the rest are in gserrordict.
|
||||
+
|
||||
+ /* If LockFilePermissions is true, we only refer to gserrordict, which
|
||||
+ * is not accessible to Postcript jobs
|
||||
*/
|
||||
- if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
|
||||
- (dict_find(perrordict, &error_name, &epref) <= 0 &&
|
||||
- (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
|
||||
- dict_find(perrordict, &error_name, &epref) <= 0))
|
||||
- )
|
||||
- return code; /* error name not in errordict??? */
|
||||
+ if (i_ctx_p->LockFilePermissions) {
|
||||
+ if (((dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
|
||||
+ dict_find(perrordict, &error_name, &epref) <= 0))
|
||||
+ )
|
||||
+ return code; /* error name not in errordict??? */
|
||||
+ }
|
||||
+ else {
|
||||
+ /*
|
||||
+ * For greater Adobe compatibility, only the standard PostScript errors
|
||||
+ * are defined in errordict; the rest are in gserrordict.
|
||||
+ */
|
||||
+ if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
|
||||
+ (dict_find(perrordict, &error_name, &epref) <= 0 &&
|
||||
+ (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
|
||||
+ dict_find(perrordict, &error_name, &epref) <= 0))
|
||||
+ )
|
||||
+ return code; /* error name not in errordict??? */
|
||||
+ }
|
||||
doref = *epref;
|
||||
epref = &doref;
|
||||
/* Push the error object on the operand stack if appropriate. */
|
||||
--
|
||||
2.18.0
|
||||
|
Reference in New Issue