Blame SOURCES/ghostscript-cve-2018-18073.patch

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