f1e96c
From: Ken Sharp <ken.sharp@artifex.com>
f1e96c
Date: Mon, 15 Oct 2018 12:35:15 +0000 (+0100)
f1e96c
Subject: font parsing - prevent SEGV in .cffparse
7c5933
f1e96c
font parsing - prevent SEGV in .cffparse
7c5933
f1e96c
Bug #699961 "currentcolortransfer procs crash .parsecff"
7c5933
f1e96c
zparsecff checked the operand for being an array (and not a packed
f1e96c
array) but the returned procedures from the default currentcolortransfer
f1e96c
are arrays, not packed arrays. This led to the code trying to
f1e96c
dereference a NULL pointer.
f1e96c
f1e96c
Add a specific check for the 'refs' pointer being NULL before we try
f1e96c
to use it.
f1e96c
f1e96c
Additionally, make the StartData procedure in the CFF Font Resource
f1e96c
executeonly to prevent pulling the hidden .parsecff operator out and
f1e96c
using it. Finally, extend this to other resource types.
f1e96c
f1e96c
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=30cd347f37bfb293ffdc407397d1023628400b81
7c5933
7c5933
From: Chris Liddell <chris.liddell@artifex.com>
f1e96c
Date: Fri, 19 Oct 2018 12:14:24 +0000 (+0100)
f1e96c
Subject: "Hide" a final use of a .force* operator
7c5933
f1e96c
"Hide" a final use of a .force* operator
f1e96c
f1e96c
There was one use of .forceput remaining that was in a regular procedure
f1e96c
rather than being "hidden" behind an operator.
f1e96c
f1e96c
In this case, it's buried in the resource machinery, and hard to access (I
f1e96c
would not be confident in claiming it was impossible). This ensures it's
f1e96c
not accessible.
f1e96c
f1e96c
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=8e18fcdaa2e2247363c4cc8f851f3096cc5756fa
f1e96c
f1e96c
From: Chris Liddell <chris.liddell@artifex.com>
f1e96c
Date: Wed, 5 Dec 2018 12:22:13 +0000 (+0000)
f1e96c
Subject: Sanitize op stack for error conditions
7c5933
7c5933
Sanitize op stack for error conditions
7c5933
7c5933
We save the stacks to an array and store the array for the error handler to
7c5933
access.
7c5933
7c5933
For SAFER, we traverse the array, and deep copy any op arrays (procedures). As
7c5933
we make these copies, we check for operators that do *not* exist in systemdict,
7c5933
when we find one, we replace the operator with a name object (of the form
7c5933
"/--opname--").
7c5933
f1e96c
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=13b0a36f8181db66a91bcc8cea139998b53a8996
f1e96c
f1e96c
From: Chris Liddell <chris.liddell@artifex.com>
f1e96c
Date: Thu, 13 Dec 2018 15:28:34 +0000 (+0000)
f1e96c
Subject: Any transient procedures that call .force* operators
f1e96c
7c5933
Any transient procedures that call .force* operators
7c5933
7c5933
(i.e. for conditionals or loops) make them executeonly.
7c5933
f1e96c
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=2db98f9c66135601efb103d8db7d020a672308db
f1e96c
f1e96c
From: Chris Liddell <chris.liddell@artifex.com>
f1e96c
Date: Sat, 15 Dec 2018 09:08:32 +0000 (+0000)
f1e96c
Subject: Bug700317: Fix logic for an older change
f1e96c
f1e96c
Bug700317: Fix logic for an older change
f1e96c
f1e96c
Unlike almost every other function in gs, dict_find_string() returns 1 on
f1e96c
success 0 or <0 on failure. The logic for this case was wrong.
f1e96c
f1e96c
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=99f13091a3f309bdc95d275ea9fec10bb9f42d9a
f1e96c
f1e96c
From: Chris Liddell <chris.liddell@artifex.com>
f1e96c
Date: Tue, 18 Dec 2018 10:42:10 +0000 (+0000)
f1e96c
Subject: Harden some uses of .force* operators
f1e96c
7c5933
Harden some uses of .force* operators
7c5933
7c5933
by adding a few immediate evalutions
7c5933
f1e96c
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=59d8f4deef90c1598ff50616519d5576756b4495
7c5933
---
7c5933
7c5933
diff -up ghostscript-9.07/psi/interp.c.cve-2019-6116 ghostscript-9.07/psi/interp.c
f1e96c
--- ghostscript-9.07/psi/interp.c.cve-2019-6116	2019-03-05 11:28:18.238244540 +0100
f1e96c
+++ ghostscript-9.07/psi/interp.c	2019-03-05 11:28:18.295243766 +0100
7c5933
@@ -692,7 +692,7 @@ again:
7c5933
                  * i.e. it's an internal operator we have hidden
7c5933
                  */
7c5933
                 code = dict_find_string(systemdict, (const char *)bufptr, &tobj);
7c5933
-                if (code < 0) {
7c5933
+                if (code <= 0) {
7c5933
                     buf[0] = buf[1] = buf[rlen + 2] = buf[rlen + 3] = '-';
7c5933
                     rlen += 4;
7c5933
                     bufptr = buf;
7c5933
@@ -751,6 +751,7 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_s
7c5933
     uint size = ref_stack_count(pstack) - skip;
7c5933
     uint save_space = ialloc_space(idmemory);
7c5933
     int code, i;
7c5933
+    ref *safety, *safe;
7c5933
 
7c5933
     if (size > 65535)
7c5933
         size = 65535;
7c5933
@@ -768,6 +769,13 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_s
7c5933
                 make_null(&arr->value.refs[i]);
7c5933
         }
7c5933
     }
7c5933
+    if (pstack == &o_stack && dict_find_string(systemdict, "SAFETY", &safety) > 0 &&
7c5933
+        dict_find_string(safety, "safe", &safe) > 0 && r_has_type(safe, t_boolean) &&
7c5933
+        safe->value.boolval == true) {
7c5933
+        code = ref_stack_array_sanitize(i_ctx_p, arr, arr);
7c5933
+        if (code < 0)
7c5933
+            return code;
7c5933
+    }
7c5933
     ialloc_set_space(idmemory, save_space);
7c5933
     return code;
7c5933
 }
7c5933
diff -up ghostscript-9.07/psi/int.mak.cve-2019-6116 ghostscript-9.07/psi/int.mak
f1e96c
--- ghostscript-9.07/psi/int.mak.cve-2019-6116	2019-03-05 11:28:18.265244173 +0100
f1e96c
+++ ghostscript-9.07/psi/int.mak	2019-03-05 11:28:18.296243753 +0100
7c5933
@@ -199,7 +199,7 @@ $(PSOBJ)iparam.$(OBJ) : $(PSSRC)iparam.c
7c5933
 $(PSOBJ)istack.$(OBJ) : $(PSSRC)istack.c $(GH) $(memory__h)\
7c5933
  $(ierrors_h) $(gsstruct_h) $(gsutil_h)\
7c5933
  $(ialloc_h) $(istack_h) $(istkparm_h) $(istruct_h) $(iutil_h) $(ivmspace_h)\
7c5933
- $(store_h)
7c5933
+ $(store_h) $(icstate_h) $(iname_h) $(dstack_h) $(idict_h)
7c5933
 	$(PSCC) $(PSO_)istack.$(OBJ) $(C_) $(PSSRC)istack.c
7c5933
 
7c5933
 $(PSOBJ)iutil.$(OBJ) : $(PSSRC)iutil.c $(GH) $(math__h) $(memory__h) $(string__h)\
7c5933
diff -up ghostscript-9.07/psi/istack.c.cve-2019-6116 ghostscript-9.07/psi/istack.c
7c5933
--- ghostscript-9.07/psi/istack.c.cve-2019-6116	2013-02-14 08:58:13.000000000 +0100
f1e96c
+++ ghostscript-9.07/psi/istack.c	2019-03-05 11:28:18.297243739 +0100
7c5933
@@ -27,6 +27,10 @@
7c5933
 #include "iutil.h"
7c5933
 #include "ivmspace.h"		/* for local/global test */
7c5933
 #include "store.h"
7c5933
+#include "icstate.h"
7c5933
+#include "iname.h"
7c5933
+#include "dstack.h"
7c5933
+#include "idict.h"
7c5933
 
7c5933
 /* Forward references */
7c5933
 static void init_block(ref_stack_t *pstack, const ref *pblock_array,
7c5933
@@ -283,6 +287,80 @@ ref_stack_store_check(const ref_stack_t
7c5933
     return 0;
7c5933
 }
7c5933
 
7c5933
+int
7c5933
+ref_stack_array_sanitize(i_ctx_t *i_ctx_p, ref *sarr, ref *darr)
7c5933
+{
7c5933
+    int i, code;
7c5933
+    ref obj, arr2;
7c5933
+    ref *pobj2;
7c5933
+    gs_memory_t *mem = (gs_memory_t *)idmemory->current;
7c5933
+
7c5933
+    if (!r_is_array(sarr) || !r_has_type(darr, t_array))
7c5933
+        return_error(gs_error_typecheck);
7c5933
+
7c5933
+    for (i = 0; i < r_size(sarr); i++) {
7c5933
+        code = array_get(mem, sarr, i, &obj);
7c5933
+        if (code < 0)
7c5933
+            make_null(&obj);
7c5933
+        switch(r_type(&obj)) {
7c5933
+          case t_operator:
7c5933
+          {
7c5933
+            int index = op_index(&obj);
7c5933
+
7c5933
+            if (index > 0 && index < op_def_count) {
7c5933
+                const byte *data = (const byte *)(op_index_def(index)->oname + 1);
7c5933
+                if (dict_find_string(systemdict, (const char *)data, &pobj2) <= 0) {
7c5933
+                    byte *s = gs_alloc_bytes(mem, strlen((char *)data) + 5, "ref_stack_array_sanitize");
7c5933
+                    if (s) {
7c5933
+                        s[0] =  '\0';
7c5933
+                        strcpy((char *)s, "--");
7c5933
+                        strcpy((char *)s + 2, (char *)data);
7c5933
+                        strcpy((char *)s + strlen((char *)data) + 2, "--");
7c5933
+                    }
7c5933
+                    else {
7c5933
+                        s = (byte *)data;
7c5933
+                    }
7c5933
+                    code = name_ref(imemory, s, strlen((char *)s), &obj, 1);
7c5933
+                    if (code < 0) make_null(&obj);
7c5933
+                    if (s != data)
7c5933
+                        gs_free_object(mem, s, "ref_stack_array_sanitize");
7c5933
+                }
7c5933
+            }
7c5933
+            else {
7c5933
+                make_null(&obj);
7c5933
+            }
7c5933
+            ref_assign(darr->value.refs + i, &obj);
7c5933
+            break;
7c5933
+          }
7c5933
+          case t_array:
7c5933
+          case t_shortarray:
7c5933
+          case t_mixedarray:
7c5933
+          {
7c5933
+            int attrs = r_type_attrs(&obj) & (a_write | a_read | a_execute | a_executable);
7c5933
+            /* We only want to copy executable arrays */
7c5933
+            if (attrs & (a_execute | a_executable)) {
7c5933
+                code = ialloc_ref_array(&arr2, attrs, r_size(&obj), "ref_stack_array_sanitize");
7c5933
+                if (code < 0) {
7c5933
+                    make_null(&arr2);
7c5933
+                }
7c5933
+                else {
7c5933
+                    code = ref_stack_array_sanitize(i_ctx_p, &obj, &arr2);
7c5933
+                }
7c5933
+                ref_assign(darr->value.refs + i, &arr2);
7c5933
+            }
7c5933
+            else {
7c5933
+                ref_assign(darr->value.refs + i, &obj);
7c5933
+            }
7c5933
+            break;
7c5933
+          }
7c5933
+          default:
7c5933
+            ref_assign(darr->value.refs + i, &obj);
7c5933
+        }
7c5933
+    }
7c5933
+    return 0;
7c5933
+}
7c5933
+
7c5933
+
7c5933
 /*
7c5933
  * Store the top 'count' elements of a stack, starting 'skip' elements below
7c5933
  * the top, into an array, with or without store/undo checking.  age=-1 for
7c5933
diff -up ghostscript-9.07/psi/istack.h.cve-2019-6116 ghostscript-9.07/psi/istack.h
7c5933
--- ghostscript-9.07/psi/istack.h.cve-2019-6116	2013-02-14 08:58:13.000000000 +0100
f1e96c
+++ ghostscript-9.07/psi/istack.h	2019-03-05 11:28:18.297243739 +0100
7c5933
@@ -129,6 +129,9 @@ int ref_stack_store(const ref_stack_t *p
7c5933
                     uint skip, int age, bool check,
7c5933
                     gs_dual_memory_t *idmem, client_name_t cname);
7c5933
 
7c5933
+int
7c5933
+ref_stack_array_sanitize(i_ctx_t *i_ctx_p, ref *sarr, ref *darr);
7c5933
+
7c5933
 /*
7c5933
  * Pop the top N elements off a stack.
7c5933
  * The number must not exceed the number of elements in use.
7c5933
diff -up ghostscript-9.07/psi/zfont2.c.cve-2019-6116 ghostscript-9.07/psi/zfont2.c
f1e96c
--- ghostscript-9.07/psi/zfont2.c.cve-2019-6116	2019-03-05 11:28:18.063246914 +0100
f1e96c
+++ ghostscript-9.07/psi/zfont2.c	2019-03-05 11:28:18.297243739 +0100
7c5933
@@ -2718,9 +2718,13 @@ zparsecff(i_ctx_t *i_ctx_p)
7c5933
     ref blk_wrap[1];
7c5933
 
7c5933
     check_read(*op);
7c5933
+
7c5933
     if (r_has_type(op, t_array)) {  /* no packedarrays */
7c5933
         int i, blk_sz, blk_cnt;
7c5933
 
7c5933
+        if (op->value.refs == NULL)
7c5933
+            return_error(gs_error_typecheck);
7c5933
+
7c5933
         data.blk_ref = op->value.refs;
7c5933
         blk_cnt  = r_size(op);
7c5933
         blk_sz = r_size(data.blk_ref);
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_cff.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_cff.ps
7c5933
--- ghostscript-9.07/Resource/Init/gs_cff.ps.cve-2019-6116	2013-02-14 08:58:16.000000000 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_cff.ps	2019-03-05 11:28:18.299243712 +0100
7c5933
@@ -719,7 +719,7 @@ dup							% Format 2
7c5933
 % ordinary CFF font.
7c5933
 /StartData {          % <resname> <nbytes> StartData -
7c5933
   currentfile exch subfilefilter //false //false ReadData pop
7c5933
-} bind def
7c5933
+} bind executeonly def
7c5933
 /ReadData {           % <resname> <file> <forceresname> <forcecid> ReadData <fontset>
7c5933
         % Initialize.
7c5933
 
7c5933
@@ -860,7 +860,7 @@ systemdict /OLDCFF known {
7c5933
   end		% FontSetInit ProcSet
7c5933
   /FontSet defineresource
7c5933
 
7c5933
-} bind def
7c5933
+} bind executeonly def
7c5933
 
7c5933
 % ---------------- Resource category definition ---------------- %
7c5933
 
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_cidcm.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_cidcm.ps
7c5933
--- ghostscript-9.07/Resource/Init/gs_cidcm.ps.cve-2019-6116	2013-02-14 08:58:16.000000000 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_cidcm.ps	2019-03-05 11:28:18.299243712 +0100
7c5933
@@ -327,7 +327,7 @@ currentdict end def
7c5933
       //FindResource exec
7c5933
     } ifelse
7c5933
   } ifelse
7c5933
-} bind def
7c5933
+} bind executeonly def
7c5933
 
7c5933
 /ResourceStatus {  % <InstName> ResourceStatus <nStatus> <nSize> true
7c5933
                    % <InstName> ResourceStatus false
7c5933
@@ -359,7 +359,7 @@ currentdict end def
7c5933
       //false
7c5933
     } ifelse
7c5933
   } ifelse
7c5933
-} bind def
7c5933
+} bind executeonly def
7c5933
 
7c5933
 /ResourceForAll { % <template> <proc> <scratch> ResourceForAll -
7c5933
 
7c5933
@@ -440,7 +440,7 @@ currentdict end def
7c5933
 
7c5933
   % Make the enumerator and apply it :
7c5933
   /MappedCategoryRedefiner /ProcSet findresource /MakeResourceEnumerator get exec exec
7c5933
-} bind def
7c5933
+} bind executeonly def
7c5933
 
7c5933
 currentdict end /Font exch /Category defineresource pop
7c5933
 end
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_ciddc.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_ciddc.ps
7c5933
--- ghostscript-9.07/Resource/Init/gs_ciddc.ps.cve-2019-6116	2013-02-14 08:58:16.000000000 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_ciddc.ps	2019-03-05 11:28:18.299243712 +0100
7c5933
@@ -202,7 +202,7 @@ begin
7c5933
     exch pop begin                                   %
7c5933
     .GetCIDDecoding
7c5933
     end
7c5933
-  } bind def
7c5933
+  } bind executeonly def
7c5933
 
7c5933
   /FindResource      % <name> FindResource <dict>
7c5933
   { currentglobal exch                               % bGlobal /InstName
7c5933
@@ -210,7 +210,7 @@ begin
7c5933
     dup //.MakeInstance exec                         % bGlobal /InstName <Inst>
7c5933
     DefineResource                                   % bGlobal <Inst>
7c5933
     exch setglobal                                   % <Inst>
7c5933
-  } bind def
7c5933
+  } bind executeonly def
7c5933
 
7c5933
 currentdict end
7c5933
 /CIDDecoding exch /Category defineresource pop
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_cmap.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_cmap.ps
7c5933
--- ghostscript-9.07/Resource/Init/gs_cmap.ps.cve-2019-6116	2013-02-14 08:58:16.000000000 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_cmap.ps	2019-03-05 11:28:18.299243712 +0100
7c5933
@@ -535,7 +535,7 @@ dup /DefineResource {
7c5933
   } if
7c5933
   dup /CodeMap .knownget { //null eq { .buildcmap } if } if
7c5933
   /Generic /Category findresource /DefineResource get exec
7c5933
-} bind put
7c5933
+} bind executeonly put
7c5933
 /Category defineresource pop
7c5933
         % We might have loaded CID font support already.
7c5933
 /CIDInit /ProcSet 2 copy { findresource } .internalstopped
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_diskn.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_diskn.ps
f1e96c
--- ghostscript-9.07/Resource/Init/gs_diskn.ps.cve-2019-6116	2019-03-05 11:28:18.255244309 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_diskn.ps	2019-03-05 11:28:18.299243712 +0100
7c5933
@@ -51,7 +51,7 @@ systemdict begin
7c5933
     mark 5 1 roll ] mark exch { { } forall } forall ]
7c5933
     //systemdict /.searchabledevs 2 index .forceput
7c5933
     exch .setglobal
7c5933
-  }
7c5933
+  } executeonly
7c5933
   if
7c5933
 } .bind executeonly odef % must be bound and hidden for .forceput
7c5933
 
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_dps1.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_dps1.ps
f1e96c
--- ghostscript-9.07/Resource/Init/gs_dps1.ps.cve-2019-6116	2019-03-05 11:28:18.288243861 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_dps1.ps	2019-03-05 11:28:18.299243712 +0100
7c5933
@@ -75,18 +75,18 @@ level2dict begin
7c5933
  } odef
7c5933
 % undefinefont has to take local/global VM into account.
7c5933
 /undefinefont		% <fontname> undefinefont -
7c5933
- { .FontDirectory 1 .argindex .forceundef	% FontDirectory is readonly
f1e96c
+ { //.FontDirectory 1 .argindex .forceundef    % FontDirectory is readonly
7c5933
    .currentglobal
7c5933
     {		% Current mode is global; delete from local directory too.
7c5933
       //systemdict /LocalFontDirectory .knownget
7c5933
-       { 1 index .forceundef }		% LocalFontDirectory is readonly
f1e96c
+       { 1 index .forceundef } executeonly             % LocalFontDirectory is readonly
7c5933
       if
7c5933
     }
7c5933
     {		% Current mode is local; if there was a shadowed global
7c5933
                 % definition, copy it into the local directory.
7c5933
       //systemdict /SharedFontDirectory .knownget
7c5933
        { 1 index .knownget
f1e96c
-          { .FontDirectory 2 index 3 -1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly
f1e96c
+          { //.FontDirectory 2 index 3 -1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly
7c5933
          if
7c5933
        }
7c5933
       if
7c5933
@@ -127,7 +127,7 @@ level2dict begin
7c5933
           }
7c5933
          ifelse
7c5933
        } forall
7c5933
-      pop counttomark 2 idiv { .forceundef } repeat pop		% readonly
f1e96c
+      pop counttomark 2 idiv { .forceundef } executeonly repeat pop            % readonly
7c5933
     }
7c5933
    if
7c5933
    //SharedFontDirectory exch .forcecopynew pop
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_fntem.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_fntem.ps
f1e96c
--- ghostscript-9.07/Resource/Init/gs_fntem.ps.cve-2019-6116	2019-03-05 11:28:18.246244431 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_fntem.ps	2019-03-05 11:28:18.299243712 +0100
7c5933
@@ -425,12 +425,12 @@ currentdict end def
7c5933
       .forceput % FontInfo can be read-only.
7c5933
       pop                                                        % bool <font>
7c5933
       exit
7c5933
-    } if
7c5933
+    } executeonly if
7c5933
     dup /FontInfo get                                            % bool <font> <FI>
7c5933
     /GlyphNames2Unicode /Unicode /Decoding findresource
7c5933
     .forceput % FontInfo can be read-only.
7c5933
     exit
7c5933
-  } loop
7c5933
+  } executeonly loop
7c5933
   exch setglobal
7c5933
 } .bind executeonly odef % must be bound and hidden for .forceput
7c5933
 
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_fonts.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_fonts.ps
f1e96c
--- ghostscript-9.07/Resource/Init/gs_fonts.ps.cve-2019-6116	2019-03-05 11:28:18.288243861 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_fonts.ps	2019-03-05 11:28:18.299243712 +0100
7c5933
@@ -505,7 +505,7 @@ buildfontdict 3 /.buildfont3 cvx put
7c5933
       if
7c5933
     }
7c5933
    if
f1e96c
-   dup .FontDirectory 4 -2 roll { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse     % readonly
f1e96c
+   dup //.FontDirectory 4 -2 roll { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse   % readonly
7c5933
                 % If the font originated as a resource, register it.
7c5933
    currentfile .currentresourcefile eq { dup .registerfont } if
7c5933
    readonly
7c5933
@@ -927,7 +927,7 @@ $error /SubstituteFont { } put
7c5933
 % Try to find a font using only the present contents of Fontmap.
7c5933
 /.tryfindfont {         % <fontname> .tryfindfont <font> true
7c5933
                         % <fontname> .tryfindfont false
7c5933
-  .FontDirectory 1 index .fontknownget
7c5933
+  //.FontDirectory 1 index .fontknownget
7c5933
     {                   % Already loaded
7c5933
       exch pop //true
7c5933
     }
7c5933
@@ -948,7 +948,7 @@ $error /SubstituteFont { } put
7c5933
                {                % Font with a procedural definition
7c5933
                  exec           % The procedure will load the font.
7c5933
                                 % Check to make sure this really happened.
7c5933
-                 .FontDirectory 1 index .knownget
7c5933
+                 //.FontDirectory 1 index .knownget
7c5933
                   { exch pop //true exit }
7c5933
                  if
7c5933
                }
7c5933
@@ -980,11 +980,11 @@ $error /SubstituteFont { } put
7c5933
 { 2 index gcheck currentglobal
7c5933
   2 copy eq {
7c5933
     pop pop .forceput
7c5933
-  } {
7c5933
+  } executeonly {
7c5933
     5 1 roll setglobal
7c5933
     dup length string copy
7c5933
     .forceput setglobal
7c5933
-  } ifelse
7c5933
+  } executeonly ifelse
7c5933
 } .bind executeonly odef % must be bound and hidden for .forceput
7c5933
 
7c5933
 % Attempt to load a font from a file.
7c5933
@@ -1060,11 +1060,11 @@ $error /SubstituteFont { } put
7c5933
                 % because it's different depending on language level.
7c5933
            .currentglobal exch /.setglobal .systemvar exec
7c5933
                 % Remove the fake definition, if any.
7c5933
-           .FontDirectory 3 index .forceundef		% readonly
7c5933
-           1 index (r) file .loadfont .FontDirectory exch
f1e96c
+           //.FontDirectory 3 index .forceundef                % readonly
7c5933
+           1 index (r) file .loadfont //.FontDirectory exch
7c5933
            /.setglobal .systemvar exec
7c5933
-         }
7c5933
-         { .loadfont .FontDirectory
7c5933
+         } executeonly
7c5933
+         { .loadfont //.FontDirectory
7c5933
          }
7c5933
         ifelse
7c5933
                 % Stack: fontname fontfilename fontdirectory
7c5933
@@ -1084,7 +1084,7 @@ $error /SubstituteFont { } put
7c5933
         dup 3 index .fontknownget
7c5933
          { dup /PathLoad 4 index //.putgstringcopy
7c5933
            4 1 roll pop pop pop //true exit
7c5933
-         } if
7c5933
+         } executeonly if
7c5933
 
7c5933
                 % Maybe the file had a different FontName.
7c5933
                 % See if we can get a FontName from the file, and if so,
f1e96c
@@ -1108,7 +1108,7 @@ $error /SubstituteFont { } put
7c5933
               ifelse  % Stack: origfontname fontdict
7c5933
               exch pop //true exit
7c5933
                       % Stack: fontdict
7c5933
-            }
7c5933
+            } executeonly
7c5933
            if pop % Stack: origfontname fontdirectory path
f1e96c
          }
7c5933
         if pop pop  % Stack: origfontname
7c5933
@@ -1146,10 +1146,10 @@ currentdict /.putgstringcopy .forceundef
7c5933
       (gs_fonts FAKEFONTS) VMDEBUG
7c5933
       Fontmap {
7c5933
         pop dup type /stringtype eq { cvn } if
7c5933
-        .FontDirectory 1 index known not {
7c5933
+        //.FontDirectory 1 index known not {
7c5933
           2 dict dup /FontName 3 index put
7c5933
           dup /FontType 1 put
f1e96c
-          .FontDirectory 3 1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse   % readonly
f1e96c
+          //.FontDirectory 3 1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse   % readonly
7c5933
         } {
7c5933
           pop
7c5933
         } ifelse
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_init.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_init.ps
f1e96c
--- ghostscript-9.07/Resource/Init/gs_init.ps.cve-2019-6116	2019-03-05 11:28:18.289243848 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_init.ps	2019-03-05 11:28:18.300243698 +0100
7c5933
@@ -1157,8 +1157,8 @@ errordict /unknownerror .undef
7c5933
   //.SAFERERRORLIST
7c5933
   {dup errordict exch get 2 index 3 1 roll put} forall
7c5933
   noaccess pop
7c5933
-  systemdict /.setsafeerrors .forceundef
7c5933
-  systemdict /.SAFERERRORLIST .forceundef
7c5933
+  //systemdict /.setsafeerrors .forceundef
7c5933
+  //systemdict /.SAFERERRORLIST .forceundef
7c5933
 } bind executeonly odef
7c5933
 
7c5933
 SAFERERRORS {.setsafererrors} if
7c5933
@@ -2080,7 +2080,7 @@ readonly def
7c5933
       /LockFilePermissions //true
7c5933
     >> setuserparams
7c5933
   }
7c5933
-  systemdict /getenv {pop //false} .forceput
7c5933
+  //systemdict /getenv {pop //false} .forceput
7c5933
   if
7c5933
   % setpagedevice has the side effect of clearing the page, but
7c5933
   % we will just document that. Using setpagedevice keeps the device
f1e96c
@@ -2305,7 +2305,7 @@ SAFER { .setsafe } if
7c5933
         % Update the copy of the user parameters.
7c5933
   mark .currentuserparams counttomark 2 idiv {
7c5933
     userparams 3 1 roll .forceput	% userparams is read-only
7c5933
-  } repeat pop
7c5933
+  } executeonly repeat pop
7c5933
         % Turn on idiom recognition, if available.
7c5933
   currentuserparams /IdiomRecognition known {
7c5933
     /IdiomRecognition //true .definepsuserparam
f1e96c
@@ -2324,7 +2324,7 @@ SAFER { .setsafe } if
7c5933
         % Remove real system params from pssystemparams.
7c5933
   mark .currentsystemparams counttomark 2 idiv {
7c5933
     pop pssystemparams exch .forceundef
7c5933
-  } repeat pop
7c5933
+  } executeonly repeat pop
7c5933
 } if
7c5933
 
7c5933
 % Set up AlignToPixels :
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_lev2.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_lev2.ps
f1e96c
--- ghostscript-9.07/Resource/Init/gs_lev2.ps.cve-2019-6116	2019-03-05 11:28:18.291243820 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_lev2.ps	2019-03-05 11:28:18.300243698 +0100
7c5933
@@ -154,7 +154,8 @@ end
7c5933
       % protect top level of parameters that we copied
7c5933
       dup type dup /arraytype eq exch /stringtype eq or { readonly } if
7c5933
       /userparams .systemvar 3 1 roll .forceput  % userparams is read-only
7c5933
-    } {
7c5933
+    } executeonly
7c5933
+    {
7c5933
       pop pop
7c5933
     } ifelse
7c5933
   } forall
7c5933
@@ -223,7 +224,7 @@ end
7c5933
          % protect top level parameters that we copied
7c5933
          dup type dup /arraytype eq exch /stringtype eq or { readonly } if
7c5933
          //pssystemparams 3 1 roll .forceput	% pssystemparams is read-only
7c5933
-       }
7c5933
+       } executeonly
7c5933
        { pop pop
7c5933
        }
7c5933
       ifelse
f1e96c
@@ -912,7 +913,7 @@ mark
7c5933
   dup /PaintProc get
7c5933
   1 index /Implementation known not {
7c5933
     1 index dup /Implementation //null .forceput readonly pop
7c5933
-  } if
7c5933
+  } executeonly if
7c5933
   exec
7c5933
 } .bind odef	% must bind .forceput
7c5933
 
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_pdfwr.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_pdfwr.ps
f1e96c
--- ghostscript-9.07/Resource/Init/gs_pdfwr.ps.cve-2019-6116	2019-03-05 11:28:18.248244404 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_pdfwr.ps	2019-03-05 11:28:18.300243698 +0100
7c5933
@@ -541,7 +541,7 @@ currentdict /.pdfmarkparams .undef
7c5933
             resourcestatus
7c5933
           } ifelse
7c5933
         } bind .makeoperator .forceput
7c5933
-      } if
7c5933
+      } executeonly if
7c5933
       pop
7c5933
     } if
7c5933
   } {
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_res.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_res.ps
7c5933
--- ghostscript-9.07/Resource/Init/gs_res.ps.cve-2019-6116	2013-02-14 08:58:16.000000000 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_res.ps	2019-03-05 11:29:42.852096773 +0100
7c5933
@@ -155,10 +155,10 @@ setglobal
7c5933
         } {
7c5933
           /defineresource cvx /typecheck signaloperror
7c5933
         } ifelse
7c5933
-} bind def
7c5933
+} bind executeonly odef
7c5933
 /FindResource		% (redefined below)
7c5933
         { .Instances exch get 0 get
7c5933
-        } bind def
7c5933
+        } bind executeonly def
7c5933
 
7c5933
                 % Additional entries
7c5933
 
7c5933
@@ -210,7 +210,7 @@ def
7c5933
       /findresource .systemvar /typecheck signalerror
7c5933
     } if
7c5933
     /findresource cvx //.findresource .errorexec
7c5933
-} odef
7c5933
+} bind executeonly odef
7c5933
 
7c5933
 /defineresource {	% <key> <instance> <category> defineresource <instance>
7c5933
     2 .argindex 2 index 2 index	% catch stackunderflow
7c5933
@@ -226,7 +226,7 @@ def
7c5933
         /DefineResource .resourceexec
7c5933
         4 1 roll pop pop pop
7c5933
     } .errorexec
7c5933
-} bind odef
7c5933
+} bind executeonly odef
7c5933
 % We must prevent resourceforall from automatically restoring the stacks,
7c5933
 % because we don't want the stacks restored if proc causes an error or
7c5933
 % executes a 'stop'. On the other hand, resourceforall is defined in the
7c5933
@@ -240,10 +240,10 @@ def
7c5933
         % Stack: <template> <proc> <scratch> <category> proc
7c5933
         exch pop		% pop the category
7c5933
         exec end
7c5933
-} bind def
7c5933
+} bind executeonly def
7c5933
 /resourceforall {	% <template> <proc> <scratch> <category> resourceforall1 -
7c5933
         //resourceforall1 exec		% see above
7c5933
-} bind odef
7c5933
+} bind executeonly odef
7c5933
 /resourcestatus {	% <key> <category> resourcestatus <status> <size> true
7c5933
                         % <key> <category> resourcestatus false
7c5933
   {
7c5933
@@ -259,7 +259,7 @@ def
7c5933
     % for error reporting. CET 23-26
7c5933
     /resourcestatus cvx $error /errorname get signalerror
7c5933
   } if
7c5933
-} bind odef
7c5933
+} bind executeonly odef
7c5933
 /undefineresource {	% <key> <category> undefineresource -
7c5933
   0 .argindex type /nametype ne {
7c5933
     /undefinedresource cvx /typecheck signaloperror
7c5933
@@ -272,7 +272,7 @@ def
7c5933
     % here but uses operator for the errors above. CET 23-33
7c5933
     /undefineresource cvx $error /errorname get signalerror
7c5933
   } if
7c5933
-} bind odef
7c5933
+} bind executeonly odef
7c5933
 
7c5933
 % Define the system parameters used for the Generic implementation of
7c5933
 % ResourceFileName.
7c5933
@@ -412,7 +412,7 @@ status {
7c5933
   } ifelse
7c5933
 } bind def
7c5933
 
7c5933
-/DefineResource {
7c5933
+/DefineResource dup {
7c5933
         .CheckResource
7c5933
            { dup [ exch 0 -1 ]
7c5933
                         % Stack: key value instance
7c5933
@@ -424,7 +424,7 @@ status {
7c5933
                         % As noted above, Category dictionaries are read-only,
7c5933
                         % so we have to use .forcedef here.
7c5933
                   /.Instances 1 index .forcedef	% Category dict is read-only
7c5933
-                } if
7c5933
+                } executeonly if
7c5933
               }
7c5933
               { .LocalInstances dup //.emptydict eq
7c5933
                  { pop 3 dict localinstancedict Category 2 index put
7c5933
@@ -441,7 +441,7 @@ status {
7c5933
            { /defineresource cvx /typecheck signaloperror
7c5933
            }
7c5933
         ifelse
7c5933
-} .bind executeonly		% executeonly to prevent access to .forcedef
f1e96c
+} .bind executeonly .makeoperator              % executeonly to prevent access to .forcedef
7c5933
 /UndefineResource
7c5933
         {  { dup 2 index .knownget
7c5933
               { dup 1 get 1 ge
7c5933
@@ -457,7 +457,7 @@ status {
7c5933
            { 2 copy .Instances exch exec
7c5933
            }
7c5933
           if .LocalInstances exch exec
7c5933
-        } bind
7c5933
+        } bind executeonly
7c5933
 % Because of some badly designed code in Adobe's CID font downloader that
7c5933
 % makes findresource and resourcestatus deliberately inconsistent with each
7c5933
 % other, the default FindResource must not call ResourceStatus if there is
7c5933
@@ -483,7 +483,7 @@ status {
7c5933
            /findresource cvx .undefinedresource
7c5933
           } ifelse
7c5933
         } ifelse
7c5933
-} bind
7c5933
+} bind executeonly
7c5933
 % Because of some badly designed code in Adobe's CID font downloader, the
7c5933
 % definition of ResourceStatus for Generic and Font must be the same (!).
7c5933
 % We patch around this by using an intermediate .ResourceFileStatus procedure.
7c5933
@@ -493,10 +493,10 @@ status {
7c5933
         } {
7c5933
           .ResourceFileStatus
7c5933
         } ifelse
7c5933
-} bind
7c5933
+} bind executeonly
7c5933
 /.ResourceFileStatus {
7c5933
         .ResourceFile { closefile 2 -1 //true } { pop //false } ifelse
7c5933
-} bind
7c5933
+} bind executeonly
7c5933
 /ResourceForAll {
7c5933
                 % Construct a new procedure to hold the arguments.
7c5933
                 % All objects constructed here must be in local VM to avoid
7c5933
@@ -554,7 +554,7 @@ status {
7c5933
         3 2 roll pop % args
7c5933
         { forall } 0 get
7c5933
         currentdict end 2 .execn begin
7c5933
-} bind
7c5933
+} bind executeonly
7c5933
 
7c5933
 /ResourceFileName  {                          % /in (scr) --> (p/c/n)
7c5933
   exch //.rfnstring cvs                       % (scr) (n)
7c5933
@@ -577,7 +577,7 @@ status {
7c5933
     } ifelse
7c5933
   } ifelse
7c5933
   exch copy                                   % (p/c/n)
7c5933
-} bind
7c5933
+} bind executeonly
7c5933
 
7c5933
                 % Additional entries
7c5933
 
7c5933
@@ -743,17 +743,17 @@ counttomark 2 idiv
7c5933
              ifelse
7c5933
            }
7c5933
           ifelse
7c5933
-        } bind
7c5933
+        } bind executeonly
7c5933
    /UndefineResource
7c5933
-        { /undefineresource cvx /invalidaccess signaloperror } bind
7c5933
+        { /undefineresource cvx /invalidaccess signaloperror } bind executeonly
7c5933
    /FindResource
7c5933
         { .Instances 1 index .knownget
7c5933
            { exch pop }
7c5933
            { /findresource cvx .undefinedresource }
7c5933
           ifelse
7c5933
-        } bind
7c5933
+        } bind executeonly
7c5933
    /ResourceStatus
7c5933
-        { .Instances exch known { 0 0 //true } { //false } ifelse } bind
7c5933
+        { .Instances exch known { 0 0 //true } { //false } ifelse } bind executeonly
7c5933
    /ResourceForAll
7c5933
         /Generic .findcategory /ResourceForAll load end
7c5933
 
7c5933
@@ -836,7 +836,7 @@ userdict /.localcsdefaults //false put
7c5933
     1 index .definedefaultcs
7c5933
     currentglobal not { .userdict /.localcsdefaults //true put } if
7c5933
   } if
7c5933
-} bind
7c5933
+} bind executeonly
7c5933
 
7c5933
 /UndefineResource {
7c5933
   dup /Generic /Category findresource /UndefineResource get exec
7c5933
@@ -859,7 +859,7 @@ userdict /.localcsdefaults //false put
7c5933
   } {
7c5933
     pop
7c5933
   } ifelse
7c5933
-} bind
7c5933
+} bind executeonly
7c5933
 
7c5933
 .definecategory			% ColorSpace
7c5933
 
7c5933
@@ -889,7 +889,7 @@ userdict /.localcsdefaults //false put
7c5933
     { exch copy exch pop }
7c5933
     { /Generic /Category findresource /ResourceFileName get exec }
7c5933
    ifelse
7c5933
- } bind
7c5933
+ } bind executeonly
7c5933
 
7c5933
 .definecategory			% Encoding
7c5933
 
7c5933
@@ -945,11 +945,11 @@ userdict /.localcsdefaults //false put
7c5933
 /DefineResource
7c5933
         { 2 copy //definefont exch pop
7c5933
           /Generic /Category findresource /DefineResource get exec
7c5933
-        } bind
7c5933
+        } bind executeonly
7c5933
 /UndefineResource
7c5933
         { dup //undefinefont
7c5933
           /Generic /Category findresource /UndefineResource get exec
7c5933
-        } bind
7c5933
+        } bind executeonly
7c5933
 /FindResource {
7c5933
         dup .getvminstance {
7c5933
           exch pop 0 get
7c5933
@@ -960,14 +960,14 @@ userdict /.localcsdefaults //false put
7c5933
             .loadfontresource
7c5933
           } ifelse
7c5933
         } ifelse
7c5933
-} bind
7c5933
+} bind executeonly
7c5933
 /ResourceForAll {
7c5933
         { .scannextfontdir not { exit } if } loop
7c5933
         /Generic /Category findresource /ResourceForAll get exec
7c5933
-} bind
7c5933
+} bind executeonly
7c5933
 /.ResourceFileStatus {
7c5933
         .fontstatus { pop 2 -1 //true } { pop //false } ifelse
7c5933
-} bind
7c5933
+} bind executeonly
7c5933
 
7c5933
 /.loadfontresource {
7c5933
         dup .vmused exch
7c5933
@@ -1017,20 +1017,20 @@ end
7c5933
   { /Font defineresource } stopped {
7c5933
       /definefont cvx $error /errorname get signalerror
7c5933
   } if
7c5933
-} bind odef
7c5933
+} bind executeonly odef
7c5933
 /undefinefont {
7c5933
   /Font undefineresource
7c5933
-} bind odef
7c5933
+} bind executeonly odef
7c5933
 % The Red Book requires that findfont be a procedure, not an operator,
7c5933
 % but it still needs to restore the stacks reliably if it fails.
7c5933
 /.findfontop {
7c5933
   { /Font findresource } stopped {
7c5933
     pop /findfont $error /errorname get signalerror
7c5933
   } if
7c5933
-} bind odef
7c5933
+} bind executeonly odef
7c5933
 /findfont {
7c5933
   .findfontop
7c5933
-} bind def	% Must be a procedure, not an operator
f1e96c
+} bind executeonly def % Must be a procedure, not an operator
7c5933
 
7c5933
 % Remove initialization utilities.
7c5933
 currentdict /.definecategory .undef
7c5933
diff -up ghostscript-9.07/Resource/Init/gs_setpd.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/gs_setpd.ps
f1e96c
--- ghostscript-9.07/Resource/Init/gs_setpd.ps.cve-2019-6116	2019-03-05 11:28:18.256244295 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/gs_setpd.ps	2019-03-05 11:28:18.301243685 +0100
7c5933
@@ -570,7 +570,7 @@ NOMEDIAATTRS {
7c5933
   SETPDDEBUG { (Rolling back.) = pstack flush } if
7c5933
   3 index 2 index 3 -1 roll .forceput
7c5933
   4 index 1 index .knownget
7c5933
-  { 4 index 3 1 roll .forceput }
7c5933
+  { 4 index 3 1 roll .forceput } executeonly
7c5933
   { 3 index exch .undef }
7c5933
   ifelse
7c5933
 } bind executeonly odef
7c5933
diff -up ghostscript-9.07/Resource/Init/pdf_base.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/pdf_base.ps
f1e96c
--- ghostscript-9.07/Resource/Init/pdf_base.ps.cve-2019-6116	2019-03-05 11:28:18.251244363 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/pdf_base.ps	2019-03-05 11:28:18.301243685 +0100
f1e96c
@@ -125,26 +125,29 @@ currentdict /num-chars-dict .undef
7c5933
 
7c5933
 /.pdfexectoken {		% <count> <opdict> <exectoken> .pdfexectoken ?
7c5933
   PDFDEBUG {
7c5933
-    pdfdict /PDFSTEPcount known not { pdfdict /PDFSTEPcount 1 .forceput } if
7c5933
+    pdfdict /PDFSTEPcount known not { pdfdict /PDFSTEPcount 1 .forceput } executeonly if
7c5933
     PDFSTEP {
7c5933
       pdfdict /PDFtokencount 2 copy .knownget { 1 add } { 1 } ifelse .forceput
7c5933
       PDFSTEPcount 1 gt {
7c5933
         pdfdict /PDFSTEPcount PDFSTEPcount 1 sub .forceput
7c5933
-      } {
f1e96c
+      } executeonly
f1e96c
+      {
7c5933
         dup ==only
7c5933
         (    step # ) print PDFtokencount =only
7c5933
         ( ? ) print flush 1 //false .outputpage
7c5933
         (%stdin) (r) file 255 string readline {
7c5933
           token {
7c5933
             exch pop pdfdict /PDFSTEPcount 3 -1 roll .forceput
7c5933
-          } {
f1e96c
+          } executeonly
f1e96c
+          {
7c5933
             pdfdict /PDFSTEPcount 1 .forceput
7c5933
-          } ifelse % token
7c5933
+          } executeonly ifelse % token
7c5933
         } {
7c5933
           pop /PDFSTEP //false def	 % EOF on stdin
7c5933
         } ifelse % readline
7c5933
       } ifelse % PDFSTEPcount > 1
7c5933
-    } {
f1e96c
+    } executeonly
f1e96c
+    {
7c5933
       dup ==only () = flush
7c5933
     } ifelse % PDFSTEP
7c5933
   } if % PDFDEBUG
7c5933
diff -up ghostscript-9.07/Resource/Init/pdf_font.ps.cve-2019-6116 ghostscript-9.07/Resource/Init/pdf_font.ps
f1e96c
--- ghostscript-9.07/Resource/Init/pdf_font.ps.cve-2019-6116	2019-03-05 11:28:18.252244350 +0100
f1e96c
+++ ghostscript-9.07/Resource/Init/pdf_font.ps	2019-03-05 11:28:18.302243671 +0100
7c5933
@@ -1757,7 +1757,7 @@ currentdict /CMap_read_dict undef
7c5933
               /CIDFallBack /CIDFont findresource
7c5933
             } if
7c5933
             exit
7c5933
-          } if
7c5933
+          } executeonly if
7c5933
         } if
7c5933
       } if
7c5933