1164f7
From: Chris Liddell <chris.liddell@artifex.com>
1164f7
Date: Wed, 10 Oct 2018 14:38:10 +0000 (+0100)
1164f7
Subject: Bug 699927: don't include operator arrays in execstack output
1164f7
1164f7
Bug 699927: don't include operator arrays in execstack output
1164f7
1164f7
When we transfer the contents of the execution stack into the array, take the
1164f7
extra step of replacing any operator arrays on the stack with the operator
1164f7
that reference them.
1164f7
1164f7
This prevents the contents of Postscript defined, internal only operators (those
1164f7
created with .makeoperator) being exposed via execstack (and thus, via error
1164f7
handling).
1164f7
1164f7
This necessitates a change in the resource remapping 'resource', which contains
1164f7
a procedure which relies on the contents of the operators arrays being present.
1164f7
As we already had internal-only variants of countexecstack and execstack
1164f7
(.countexecstack and .execstack) - using those, and leaving thier operation
1164f7
including the operator arrays means the procedure continues to work correctly.
1164f7
1164f7
Both .countexecstack and .execstack are undefined after initialization.
1164f7
1164f7
Also, when we store the execstack (or part thereof) for an execstackoverflow
1164f7
error, make the same oparray/operator substitution as above for execstack.
1164f7
1164f7
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=34cc326eb2c5695833361887fe0b32e8d987741c
1164f7
1164f7
From: Chris Liddell <chris.liddell@artifex.com>
1164f7
Date: Tue, 25 Sep 2018 14:38:14 +0000 (+0100)
1164f7
Subject: Bug 699793: Hide the .needinput operator
1164f7
1164f7
Bug 699793: Hide the .needinput operator
1164f7
1164f7
This removes the .needinput operator from systemdict, ensuring it can only
1164f7
be used in the initialization code, and not called erroneously from random
1164f7
Postscript.
1164f7
1164f7
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=f8ccc7dfb990336b1ca55f65f2e1a8ecdcb76adf
1164f7
---
1164f7
1164f7
diff -up ghostscript-9.07/psi/interp.c.cve-2018-18073 ghostscript-9.07/psi/interp.c
1164f7
--- ghostscript-9.07/psi/interp.c.cve-2018-18073	2018-12-05 15:15:27.071274267 +0100
1164f7
+++ ghostscript-9.07/psi/interp.c	2018-12-05 15:15:27.077274220 +0100
1164f7
@@ -142,7 +142,6 @@ static int oparray_pop(i_ctx_t *);
1164f7
 static int oparray_cleanup(i_ctx_t *);
1164f7
 static int zerrorexec(i_ctx_t *);
1164f7
 static int zfinderrorobject(i_ctx_t *);
1164f7
-static int errorexec_find(i_ctx_t *, ref *);
1164f7
 static int errorexec_pop(i_ctx_t *);
1164f7
 static int errorexec_cleanup(i_ctx_t *);
1164f7
 static int zsetstackprotect(i_ctx_t *);
1164f7
@@ -751,7 +750,7 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_s
1164f7
 {
1164f7
     uint size = ref_stack_count(pstack) - skip;
1164f7
     uint save_space = ialloc_space(idmemory);
1164f7
-    int code;
1164f7
+    int code, i;
1164f7
 
1164f7
     if (size > 65535)
1164f7
         size = 65535;
1164f7
@@ -760,6 +759,15 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_s
1164f7
     if (code >= 0)
1164f7
         code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory,
1164f7
                                "copy_stack");
1164f7
+    /* If we are copying the exec stack, try to replace any oparrays with
1164f7
+     * with the operator than references them
1164f7
+     */
1164f7
+    if (pstack == &e_stack) {
1164f7
+        for (i = 0; i < size; i++) {
1164f7
+            if (errorexec_find(i_ctx_p, &arr->value.refs[i]) < 0)
1164f7
+                make_null(&arr->value.refs[i]);
1164f7
+        }
1164f7
+    }
1164f7
     ialloc_set_space(idmemory, save_space);
1164f7
     return code;
1164f7
 }
1164f7
@@ -1908,7 +1916,7 @@ zfinderrorobject(i_ctx_t *i_ctx_p)
1164f7
  * .errorexec with errobj != null, store it in *perror_object and return 1,
1164f7
  * otherwise return 0;
1164f7
  */
1164f7
-static int
1164f7
+int
1164f7
 errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object)
1164f7
 {
1164f7
     long i;
1164f7
diff -up ghostscript-9.07/psi/interp.h.cve-2018-18073 ghostscript-9.07/psi/interp.h
1164f7
--- ghostscript-9.07/psi/interp.h.cve-2018-18073	2013-02-14 08:58:13.000000000 +0100
1164f7
+++ ghostscript-9.07/psi/interp.h	2018-12-05 15:15:27.077274220 +0100
1164f7
@@ -92,5 +92,7 @@ void gs_interp_reset(i_ctx_t *i_ctx_p);
1164f7
 /* Define the top-level interface to the interpreter. */
1164f7
 int gs_interpret(i_ctx_t **pi_ctx_p, ref * pref, int user_errors,
1164f7
                  int *pexit_code, ref * perror_object);
1164f7
+int
1164f7
+errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object);
1164f7
 
1164f7
 #endif /* interp_INCLUDED */
1164f7
diff -up ghostscript-9.07/psi/int.mak.cve-2018-18073 ghostscript-9.07/psi/int.mak
1164f7
--- ghostscript-9.07/psi/int.mak.cve-2018-18073	2018-12-05 15:15:27.017274689 +0100
1164f7
+++ ghostscript-9.07/psi/int.mak	2018-12-05 15:15:27.077274220 +0100
1164f7
@@ -317,7 +317,8 @@ $(PSOBJ)zarray.$(OBJ) : $(PSSRC)zarray.c
1164f7
 	$(PSCC) $(PSO_)zarray.$(OBJ) $(C_) $(PSSRC)zarray.c
1164f7
 
1164f7
 $(PSOBJ)zcontrol.$(OBJ) : $(PSSRC)zcontrol.c $(OP) $(string__h)\
1164f7
- $(estack_h) $(files_h) $(ipacked_h) $(iutil_h) $(store_h) $(stream_h)
1164f7
+ $(estack_h) $(files_h) $(ipacked_h) $(iutil_h) $(store_h) $(stream_h)\
1164f7
+ $(interp_h)
1164f7
 	$(PSCC) $(PSO_)zcontrol.$(OBJ) $(C_) $(PSSRC)zcontrol.c
1164f7
 
1164f7
 $(PSOBJ)zdict.$(OBJ) : $(PSSRC)zdict.c $(OP)\
1164f7
diff -up ghostscript-9.07/psi/zcontrol.c.cve-2018-18073 ghostscript-9.07/psi/zcontrol.c
1164f7
--- ghostscript-9.07/psi/zcontrol.c.cve-2018-18073	2013-02-14 08:58:13.000000000 +0100
1164f7
+++ ghostscript-9.07/psi/zcontrol.c	2018-12-05 15:15:27.077274220 +0100
1164f7
@@ -24,6 +24,7 @@
1164f7
 #include "ipacked.h"
1164f7
 #include "iutil.h"
1164f7
 #include "store.h"
1164f7
+#include "interp.h"
1164f7
 
1164f7
 /* Forward references */
1164f7
 static int check_for_exec(const_os_ptr);
1164f7
@@ -785,7 +786,7 @@ zexecstack2(i_ctx_t *i_ctx_p)
1164f7
 /* Continuation operator to do the actual transfer. */
1164f7
 /* r_size(op1) was set just above. */
1164f7
 static int
1164f7
-do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1)
1164f7
+do_execstack(i_ctx_t *i_ctx_p, bool include_marks, bool include_oparrays, os_ptr op1)
1164f7
 {
1164f7
     os_ptr op = osp;
1164f7
     ref *arefs = op1->value.refs;
1164f7
@@ -827,6 +828,12 @@ do_execstack(i_ctx_t *i_ctx_p, bool incl
1164f7
                                   strlen(tname), (const byte *)tname);
1164f7
                 break;
1164f7
             }
1164f7
+            case t_array:
1164f7
+            case t_shortarray:
1164f7
+            case t_mixedarray:
1164f7
+                if (!include_oparrays && errorexec_find(i_ctx_p, rq) < 0)
1164f7
+                    make_null(rq);
1164f7
+                break;
1164f7
             default:
1164f7
                 ;
1164f7
         }
1164f7
@@ -839,14 +846,14 @@ execstack_continue(i_ctx_t *i_ctx_p)
1164f7
 {
1164f7
     os_ptr op = osp;
1164f7
 
1164f7
-    return do_execstack(i_ctx_p, false, op);
1164f7
+    return do_execstack(i_ctx_p, false, false, op);
1164f7
 }
1164f7
 static int
1164f7
 execstack2_continue(i_ctx_t *i_ctx_p)
1164f7
 {
1164f7
     os_ptr op = osp;
1164f7
 
1164f7
-    return do_execstack(i_ctx_p, op->value.boolval, op - 1);
1164f7
+    return do_execstack(i_ctx_p, op->value.boolval, true, op - 1);
1164f7
 }
1164f7
 
1164f7
 /* - .needinput - */
1164f7
diff -up ghostscript-9.07/Resource/Init/gs_init.ps.cve-2018-18073 ghostscript-9.07/Resource/Init/gs_init.ps
1164f7
--- ghostscript-9.07/Resource/Init/gs_init.ps.cve-2018-18073	2018-12-05 15:15:27.073274252 +0100
1164f7
+++ ghostscript-9.07/Resource/Init/gs_init.ps	2018-12-05 15:18:55.848645627 +0100
1164f7
@@ -839,12 +839,26 @@ userdict /.currentresourcefile //null pu
1164f7
 /.runstring {
1164f7
   0 0 .systemvmstring .systemvmSFD cvx { .runexec } execute0
1164f7
 } bind def
1164f7
+
1164f7
 % Define the procedure that the C code uses to set up for executing
1164f7
 % a string that may be received in pieces.
1164f7
+%
1164f7
+% Immediate evaluation doesn't work on operators (like .needinput)
1164f7
+% so calling .runstringbegin will throw an undefined error if we
1164f7
+% undefined .needinput so it cannot be accessed outside the init
1164f7
+% code. But, we can store the operator in an array, use immediate
1164f7
+% evaluation on the array to get the operator, then undefined the
1164f7
+% array (and because they are both of the same name, the operator
1164f7
+% get undefined too).
1164f7
+% This prevents random Postscript from erroneously calling .needinput
1164f7
+% and forcing the interpreter into an invalid state.
1164f7
+/.needinput
1164f7
+1 .systemvmarray dup 0 /.needinput load put
1164f7
+def
1164f7
 /.runstringbegin {
1164f7
-  1 .systemvmarray dup 0 /.needinput load put cvx	% { .needinput } in systemvm
1164f7
+  1 .systemvmarray dup 0 //.needinput 0 get put cvx    % { .needinput } in systemvm
1164f7
   0 0 .systemvmstring .systemvmSFD cvx .runexec
1164f7
-} bind def
1164f7
+} bind executeonly def
1164f7
 
1164f7
 % Define a special version of runlibfile that aborts on errors.
1164f7
 /runlibfile0
1164f7
@@ -2147,7 +2161,7 @@ SAFER { .setsafe } if
1164f7
 %% but can be easily restored (just delete the name from the list in the array). In future
1164f7
 %% we may remove the operator and the code implementation entirely.
1164f7
 [
1164f7
-/.bitadd /.charboxpath /.currentblackptcomp /.setblackptcomp /.cond /.countexecstack /.execstack /.runandhide /.popdevicefilter
1164f7
+/.bitadd /.charboxpath /.cond /.runandhide /.popdevicefilter
1164f7
 /.execfile /.filenamesplit /.file_name_parent
1164f7
 /.setdefaultmatrix /.isprocfilter /.unread /.psstringencode
1164f7
 /.buildsampledfunction /.isencapfunction /.currentaccuratecurves /.currentcurvejoin /.currentdashadapt /.currentdotlength
1164f7
@@ -2186,6 +2200,7 @@ SAFER { .setsafe } if
1164f7
 /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
1164f7
 /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
1164f7
 /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice
1164f7
+/.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack
1164f7
 
1164f7
 % Used by a free user in the Library of Congress. Apparently this is used to
1164f7
 % draw a partial page, which is then filled in by the results of a barcode
1164f7
@@ -2204,7 +2219,7 @@ SAFER { .setsafe } if
1164f7
 % test files/utilities, or engineers expressed a desire to keep them visible.
1164f7
 %
1164f7
 %/currentdevice /.sort /.buildfont0 /.buildfont1 /.buildfont2 /.buildfont3 /.buildfont4 /.buildfont9 /.buildfont10 /.buildfont11
1164f7
-%/.buildfotn32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors
1164f7
+%/.buildfont32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors
1164f7
 %/currentdevice  /.quit /.setuseciecolor /.needinput /.setoverprintmode /.special_op /.dicttomark /.knownget
1164f7
 %/.FAPIavailable /.FAPIpassfont /.FAPIrebuildfont /.FAPIBuildGlyph /.FAPIBuildChar /.FAPIBuildGlyph9
1164f7
 %/.tempfile /.numicc_components /.set_outputintent  /.max /.min /.vmreclaim /.getpath /.setglobal
1164f7
diff -up ghostscript-9.07/Resource/Init/gs_resmp.ps.cve-2018-18073 ghostscript-9.07/Resource/Init/gs_resmp.ps
1164f7
--- ghostscript-9.07/Resource/Init/gs_resmp.ps.cve-2018-18073	2013-02-14 08:58:16.000000000 +0100
1164f7
+++ ghostscript-9.07/Resource/Init/gs_resmp.ps	2018-12-05 15:15:27.078274212 +0100
1164f7
@@ -183,7 +183,7 @@ setpacking
1164f7
   % We don't check them.
1164f7
 
1164f7
   currentglobal //false setglobal                  % <object> bGlobal
1164f7
-  countexecstack array execstack                   % <object> bGlobal [execstack]
1164f7
+  //false .countexecstack array //false .execstack % <object> bGlobal [execstack]
1164f7
   dup //null exch                                  % <object> bGlobal [execstack] null [execstack]
1164f7
   length 3 sub -1 0 {                              % <object> bGlobal [execstack] null i
1164f7
     2 index exch get                               % <object> bGlobal [execstack] null proc