summary refs log tree commit diff
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
+