aboutsummaryrefslogtreecommitdiff
path: root/gnu/packages/patches/ghostscript-bug-699708.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages/patches/ghostscript-bug-699708.patch')
-rw-r--r--gnu/packages/patches/ghostscript-bug-699708.patch160
1 files changed, 160 insertions, 0 deletions
diff --git a/gnu/packages/patches/ghostscript-bug-699708.patch b/gnu/packages/patches/ghostscript-bug-699708.patch
new file mode 100644
index 0000000000..1567be1c6f
--- /dev/null
+++ b/gnu/packages/patches/ghostscript-bug-699708.patch
@@ -0,0 +1,160 @@
+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
+