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

38aaa9
From c76bf1cb7cc419534006631ea139ae20801fd824 Mon Sep 17 00:00:00 2001
38aaa9
From: Nancy Durgin <nancy.durgin@artifex.com>
38aaa9
Date: Tue, 18 Sep 2018 11:54:58 -0700
38aaa9
Subject: [PATCH 1/3] Undefine some additional internal operators.
38aaa9
38aaa9
.type, .writecvs, .setSMask, .currentSMask
38aaa9
38aaa9
These don't seem to be referenced anywhere outside of the initialization code,
38aaa9
which binds their usages.  Passes cluster if they are removed.
38aaa9
---
38aaa9
 Resource/Init/gs_init.ps | 3 ++-
38aaa9
 1 file changed, 2 insertions(+), 1 deletion(-)
38aaa9
38aaa9
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
38aaa9
index 55d6923..4aff036 100644
38aaa9
--- a/Resource/Init/gs_init.ps
38aaa9
+++ b/Resource/Init/gs_init.ps
38aaa9
@@ -2212,6 +2212,7 @@ SAFER { .setsafeglobal } if
38aaa9
   /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
38aaa9
   /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
38aaa9
   /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice
38aaa9
+  /.type /.writecvs /.setSMask /.currentSMask
38aaa9
 
38aaa9
   % Used by a free user in the Library of Congress. Apparently this is used to
38aaa9
   % draw a partial page, which is then filled in by the results of a barcode
38aaa9
@@ -2230,7 +2231,7 @@ SAFER { .setsafeglobal } if
38aaa9
   % test files/utilities, or engineers expressed a desire to keep them visible.
38aaa9
   %
38aaa9
   %/currentdevice /.sort /.buildfont0 /.buildfont1 /.buildfont2 /.buildfont3 /.buildfont4 /.buildfont9 /.buildfont10 /.buildfont11
38aaa9
-  %/.buildfotn32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors
38aaa9
+  %/.buildfont32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors
38aaa9
   %/currentdevice  /.quit /.setuseciecolor /.needinput /.setoverprintmode /.special_op /.dicttomark /.knownget
38aaa9
   %/.FAPIavailable /.FAPIpassfont /.FAPIrebuildfont /.FAPIBuildGlyph /.FAPIBuildChar /.FAPIBuildGlyph9
38aaa9
   %/.tempfile /.numicc_components /.set_outputintent  /.max /.min /.vmreclaim /.getpath /.setglobal
38aaa9
-- 
38aaa9
2.17.2
38aaa9
38aaa9
38aaa9
From f8ccc7dfb990336b1ca55f65f2e1a8ecdcb76adf Mon Sep 17 00:00:00 2001
38aaa9
From: Chris Liddell <chris.liddell@artifex.com>
38aaa9
Date: Tue, 25 Sep 2018 15:38:14 +0100
38aaa9
Subject: [PATCH 2/3] Bug 699793: Hide the .needinput operator
38aaa9
38aaa9
This removes the .needinput operator from systemdict, ensuring it can only
38aaa9
be used in the initialization code, and not called erroneously from random
38aaa9
Postscript.
38aaa9
---
38aaa9
 Resource/Init/gs_init.ps | 20 +++++++++++++++++---
38aaa9
 1 file changed, 17 insertions(+), 3 deletions(-)
38aaa9
38aaa9
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
38aaa9
index 4aff036..6a5c1df 100644
38aaa9
--- a/Resource/Init/gs_init.ps
38aaa9
+++ b/Resource/Init/gs_init.ps
38aaa9
@@ -831,12 +831,26 @@ userdict /.currentresourcefile //null put
38aaa9
 /.runstring {
38aaa9
   0 0 .systemvmstring .systemvmSFD cvx { .runexec } execute0
38aaa9
 } bind def
38aaa9
+
38aaa9
 % Define the procedure that the C code uses to set up for executing
38aaa9
 % a string that may be received in pieces.
38aaa9
+%
38aaa9
+% Immediate evaluation doesn't work on operators (like .needinput)
38aaa9
+% so calling .runstringbegin will throw an undefined error if we
38aaa9
+% undefined .needinput so it cannot be accessed outside the init
38aaa9
+% code. But, we can store the operator in an array, use immediate
38aaa9
+% evaluation on the array to get the operator, then undefined the
38aaa9
+% array (and because they are both of the same name, the operator
38aaa9
+% get undefined too).
38aaa9
+% This prevents random Postscript from erroneously calling .needinput
38aaa9
+% and forcing the interpreter into an invalid state.
38aaa9
+/.needinput
38aaa9
+1 .systemvmarray dup 0 /.needinput load put
38aaa9
+def
38aaa9
 /.runstringbegin {
38aaa9
-  1 .systemvmarray dup 0 /.needinput load put cvx	% { .needinput } in systemvm
38aaa9
+  1 .systemvmarray dup 0 //.needinput 0 get put cvx	% { .needinput } in systemvm
38aaa9
   0 0 .systemvmstring .systemvmSFD cvx .runexec
38aaa9
-} bind def
38aaa9
+} bind executeonly def
38aaa9
 
38aaa9
 % Define a special version of runlibfile that aborts on errors.
38aaa9
 /runlibfile0
38aaa9
@@ -2212,7 +2226,7 @@ SAFER { .setsafeglobal } if
38aaa9
   /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
38aaa9
   /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
38aaa9
   /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice
38aaa9
-  /.type /.writecvs /.setSMask /.currentSMask
38aaa9
+  /.type /.writecvs /.setSMask /.currentSMask /.needinput
38aaa9
 
38aaa9
   % Used by a free user in the Library of Congress. Apparently this is used to
38aaa9
   % draw a partial page, which is then filled in by the results of a barcode
38aaa9
-- 
38aaa9
2.17.2
38aaa9
38aaa9
38aaa9
From 34cc326eb2c5695833361887fe0b32e8d987741c Mon Sep 17 00:00:00 2001
38aaa9
From: Chris Liddell <chris.liddell@artifex.com>
38aaa9
Date: Wed, 10 Oct 2018 15:38:10 +0100
38aaa9
Subject: [PATCH 3/3] Bug 699927: don't include operator arrays in execstack
38aaa9
 output
38aaa9
38aaa9
When we transfer the contents of the execution stack into the array, take the
38aaa9
extra step of replacing any operator arrays on the stack with the operator
38aaa9
that reference them.
38aaa9
38aaa9
This prevents the contents of Postscript defined, internal only operators (those
38aaa9
created with .makeoperator) being exposed via execstack (and thus, via error
38aaa9
handling).
38aaa9
38aaa9
This necessitates a change in the resource remapping 'resource', which contains
38aaa9
a procedure which relies on the contents of the operators arrays being present.
38aaa9
As we already had internal-only variants of countexecstack and execstack
38aaa9
(.countexecstack and .execstack) - using those, and leaving thier operation
38aaa9
including the operator arrays means the procedure continues to work correctly.
38aaa9
38aaa9
Both .countexecstack and .execstack are undefined after initialization.
38aaa9
38aaa9
Also, when we store the execstack (or part thereof) for an execstackoverflow
38aaa9
error, make the same oparray/operator substitution as above for execstack.
38aaa9
---
38aaa9
 Resource/Init/gs_init.ps  |  4 ++--
38aaa9
 Resource/Init/gs_resmp.ps |  2 +-
38aaa9
 psi/int.mak               |  2 +-
38aaa9
 psi/interp.c              | 14 +++++++++++---
38aaa9
 psi/interp.h              |  2 ++
38aaa9
 psi/zcontrol.c            | 13 ++++++++++---
38aaa9
 6 files changed, 27 insertions(+), 10 deletions(-)
38aaa9
38aaa9
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
38aaa9
index 6a5c1df..5bec480 100644
38aaa9
--- a/Resource/Init/gs_init.ps
38aaa9
+++ b/Resource/Init/gs_init.ps
38aaa9
@@ -2187,7 +2187,7 @@ SAFER { .setsafeglobal } if
38aaa9
   %% but can be easily restored (just delete the name from the list in the array). In future
38aaa9
   %% we may remove the operator and the code implementation entirely.
38aaa9
   [
38aaa9
-  /.bitadd /.charboxpath /.cond /.countexecstack /.execstack /.runandhide /.popdevicefilter
38aaa9
+  /.bitadd /.charboxpath /.cond /.runandhide /.popdevicefilter
38aaa9
   /.execfile /.filenamesplit /.file_name_parent
38aaa9
   /.setdefaultmatrix /.isprocfilter /.unread /.psstringencode
38aaa9
   /.buildsampledfunction /.isencapfunction /.currentaccuratecurves /.currentcurvejoin /.currentdashadapt /.currentdotlength
38aaa9
@@ -2226,7 +2226,7 @@ SAFER { .setsafeglobal } if
38aaa9
   /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
38aaa9
   /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
38aaa9
   /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice
38aaa9
-  /.type /.writecvs /.setSMask /.currentSMask /.needinput
38aaa9
+  /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack
38aaa9
 
38aaa9
   % Used by a free user in the Library of Congress. Apparently this is used to
38aaa9
   % draw a partial page, which is then filled in by the results of a barcode
38aaa9
diff --git a/Resource/Init/gs_resmp.ps b/Resource/Init/gs_resmp.ps
38aaa9
index 7cacaf8..9bb4263 100644
38aaa9
--- a/Resource/Init/gs_resmp.ps
38aaa9
+++ b/Resource/Init/gs_resmp.ps
38aaa9
@@ -183,7 +183,7 @@ setpacking
38aaa9
   % We don't check them.
38aaa9
 
38aaa9
   currentglobal //false setglobal                  % <object> bGlobal
38aaa9
-  countexecstack array execstack                   % <object> bGlobal [execstack]
38aaa9
+  //false .countexecstack array //false .execstack % <object> bGlobal [execstack]
38aaa9
   dup //null exch                                  % <object> bGlobal [execstack] null [execstack]
38aaa9
   length 3 sub -1 0 {                              % <object> bGlobal [execstack] null i
38aaa9
     2 index exch get                               % <object> bGlobal [execstack] null proc
38aaa9
diff --git a/psi/int.mak b/psi/int.mak
38aaa9
index 5d9b3d5..6ab5bf0 100644
38aaa9
--- a/psi/int.mak
38aaa9
+++ b/psi/int.mak
38aaa9
@@ -323,7 +323,7 @@ $(PSOBJ)zarray.$(OBJ) : $(PSSRC)zarray.c $(OP) $(memory__h)\
38aaa9
 
38aaa9
 $(PSOBJ)zcontrol.$(OBJ) : $(PSSRC)zcontrol.c $(OP) $(string__h)\
38aaa9
  $(estack_h) $(files_h) $(ipacked_h) $(iutil_h) $(store_h) $(stream_h)\
38aaa9
- $(INT_MAK) $(MAKEDIRS)
38aaa9
+ $(interp_h) $(INT_MAK) $(MAKEDIRS)
38aaa9
 	$(PSCC) $(PSO_)zcontrol.$(OBJ) $(C_) $(PSSRC)zcontrol.c
38aaa9
 
38aaa9
 $(PSOBJ)zdict.$(OBJ) : $(PSSRC)zdict.c $(OP)\
38aaa9
diff --git a/psi/interp.c b/psi/interp.c
38aaa9
index 3dd5f7a..1dec9b6 100644
38aaa9
--- a/psi/interp.c
38aaa9
+++ b/psi/interp.c
38aaa9
@@ -142,7 +142,6 @@ static int oparray_pop(i_ctx_t *);
38aaa9
 static int oparray_cleanup(i_ctx_t *);
38aaa9
 static int zerrorexec(i_ctx_t *);
38aaa9
 static int zfinderrorobject(i_ctx_t *);
38aaa9
-static int errorexec_find(i_ctx_t *, ref *);
38aaa9
 static int errorexec_pop(i_ctx_t *);
38aaa9
 static int errorexec_cleanup(i_ctx_t *);
38aaa9
 static int zsetstackprotect(i_ctx_t *);
38aaa9
@@ -737,7 +736,7 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
38aaa9
 {
38aaa9
     uint size = ref_stack_count(pstack) - skip;
38aaa9
     uint save_space = ialloc_space(idmemory);
38aaa9
-    int code;
38aaa9
+    int code, i;
38aaa9
 
38aaa9
     if (size > 65535)
38aaa9
         size = 65535;
38aaa9
@@ -746,6 +745,15 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
38aaa9
     if (code >= 0)
38aaa9
         code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory,
38aaa9
                                "copy_stack");
38aaa9
+    /* If we are copying the exec stack, try to replace any oparrays with
38aaa9
+     * with the operator than references them
38aaa9
+     */
38aaa9
+    if (pstack == &e_stack) {
38aaa9
+        for (i = 0; i < size; i++) {
38aaa9
+            if (errorexec_find(i_ctx_p, &arr->value.refs[i]) < 0)
38aaa9
+                make_null(&arr->value.refs[i]);
38aaa9
+        }
38aaa9
+    }
38aaa9
     ialloc_set_space(idmemory, save_space);
38aaa9
     return code;
38aaa9
 }
38aaa9
@@ -1910,7 +1918,7 @@ zfinderrorobject(i_ctx_t *i_ctx_p)
38aaa9
  * .errorexec with errobj != null, store it in *perror_object and return 1,
38aaa9
  * otherwise return 0;
38aaa9
  */
38aaa9
-static int
38aaa9
+int
38aaa9
 errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object)
38aaa9
 {
38aaa9
     long i;
38aaa9
diff --git a/psi/interp.h b/psi/interp.h
38aaa9
index e9275b9..4f551d1 100644
38aaa9
--- a/psi/interp.h
38aaa9
+++ b/psi/interp.h
38aaa9
@@ -91,5 +91,7 @@ void gs_interp_reset(i_ctx_t *i_ctx_p);
38aaa9
 /* Define the top-level interface to the interpreter. */
38aaa9
 int gs_interpret(i_ctx_t **pi_ctx_p, ref * pref, int user_errors,
38aaa9
                  int *pexit_code, ref * perror_object);
38aaa9
+int
38aaa9
+errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object);
38aaa9
 
38aaa9
 #endif /* interp_INCLUDED */
38aaa9
diff --git a/psi/zcontrol.c b/psi/zcontrol.c
38aaa9
index 36da22c..0362cf4 100644
38aaa9
--- a/psi/zcontrol.c
38aaa9
+++ b/psi/zcontrol.c
38aaa9
@@ -24,6 +24,7 @@
38aaa9
 #include "ipacked.h"
38aaa9
 #include "iutil.h"
38aaa9
 #include "store.h"
38aaa9
+#include "interp.h"
38aaa9
 
38aaa9
 /* Forward references */
38aaa9
 static int check_for_exec(const_os_ptr);
38aaa9
@@ -787,7 +788,7 @@ zexecstack2(i_ctx_t *i_ctx_p)
38aaa9
 /* Continuation operator to do the actual transfer. */
38aaa9
 /* r_size(op1) was set just above. */
38aaa9
 static int
38aaa9
-do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1)
38aaa9
+do_execstack(i_ctx_t *i_ctx_p, bool include_marks, bool include_oparrays, os_ptr op1)
38aaa9
 {
38aaa9
     os_ptr op = osp;
38aaa9
     ref *arefs = op1->value.refs;
38aaa9
@@ -829,6 +830,12 @@ do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1)
38aaa9
                                   strlen(tname), (const byte *)tname);
38aaa9
                 break;
38aaa9
             }
38aaa9
+            case t_array:
38aaa9
+            case t_shortarray:
38aaa9
+            case t_mixedarray:
38aaa9
+                if (!include_oparrays && errorexec_find(i_ctx_p, rq) < 0)
38aaa9
+                    make_null(rq);
38aaa9
+                break;
38aaa9
             default:
38aaa9
                 ;
38aaa9
         }
38aaa9
@@ -841,14 +848,14 @@ execstack_continue(i_ctx_t *i_ctx_p)
38aaa9
 {
38aaa9
     os_ptr op = osp;
38aaa9
 
38aaa9
-    return do_execstack(i_ctx_p, false, op);
38aaa9
+    return do_execstack(i_ctx_p, false, false, op);
38aaa9
 }
38aaa9
 static int
38aaa9
 execstack2_continue(i_ctx_t *i_ctx_p)
38aaa9
 {
38aaa9
     os_ptr op = osp;
38aaa9
 
38aaa9
-    return do_execstack(i_ctx_p, op->value.boolval, op - 1);
38aaa9
+    return do_execstack(i_ctx_p, op->value.boolval, true, op - 1);
38aaa9
 }
38aaa9
 
38aaa9
 /* - .needinput - */
38aaa9
-- 
38aaa9
2.17.2
38aaa9