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

ed4834
From c76bf1cb7cc419534006631ea139ae20801fd824 Mon Sep 17 00:00:00 2001
ed4834
From: Nancy Durgin <nancy.durgin@artifex.com>
ed4834
Date: Tue, 18 Sep 2018 11:54:58 -0700
ed4834
Subject: [PATCH 1/3] Undefine some additional internal operators.
ed4834
ed4834
.type, .writecvs, .setSMask, .currentSMask
ed4834
ed4834
These don't seem to be referenced anywhere outside of the initialization code,
ed4834
which binds their usages.  Passes cluster if they are removed.
ed4834
---
ed4834
 Resource/Init/gs_init.ps | 3 ++-
ed4834
 1 file changed, 2 insertions(+), 1 deletion(-)
ed4834
ed4834
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
ed4834
index 55d6923..4aff036 100644
ed4834
--- a/Resource/Init/gs_init.ps
ed4834
+++ b/Resource/Init/gs_init.ps
ed4834
@@ -2212,6 +2212,7 @@ SAFER { .setsafeglobal } if
ed4834
   /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
ed4834
   /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
ed4834
   /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice
ed4834
+  /.type /.writecvs /.setSMask /.currentSMask
ed4834
 
ed4834
   % Used by a free user in the Library of Congress. Apparently this is used to
ed4834
   % draw a partial page, which is then filled in by the results of a barcode
ed4834
@@ -2230,7 +2231,7 @@ SAFER { .setsafeglobal } if
ed4834
   % test files/utilities, or engineers expressed a desire to keep them visible.
ed4834
   %
ed4834
   %/currentdevice /.sort /.buildfont0 /.buildfont1 /.buildfont2 /.buildfont3 /.buildfont4 /.buildfont9 /.buildfont10 /.buildfont11
ed4834
-  %/.buildfotn32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors
ed4834
+  %/.buildfont32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors
ed4834
   %/currentdevice  /.quit /.setuseciecolor /.needinput /.setoverprintmode /.special_op /.dicttomark /.knownget
ed4834
   %/.FAPIavailable /.FAPIpassfont /.FAPIrebuildfont /.FAPIBuildGlyph /.FAPIBuildChar /.FAPIBuildGlyph9
ed4834
   %/.tempfile /.numicc_components /.set_outputintent  /.max /.min /.vmreclaim /.getpath /.setglobal
ed4834
-- 
ed4834
2.17.2
ed4834
ed4834
ed4834
From f8ccc7dfb990336b1ca55f65f2e1a8ecdcb76adf Mon Sep 17 00:00:00 2001
09061c
From: Chris Liddell <chris.liddell@artifex.com>
ed4834
Date: Tue, 25 Sep 2018 15:38:14 +0100
ed4834
Subject: [PATCH 2/3] Bug 699793: Hide the .needinput operator
09061c
ed4834
This removes the .needinput operator from systemdict, ensuring it can only
ed4834
be used in the initialization code, and not called erroneously from random
ed4834
Postscript.
ed4834
---
ed4834
 Resource/Init/gs_init.ps | 20 +++++++++++++++++---
ed4834
 1 file changed, 17 insertions(+), 3 deletions(-)
ed4834
ed4834
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
ed4834
index 4aff036..6a5c1df 100644
ed4834
--- a/Resource/Init/gs_init.ps
ed4834
+++ b/Resource/Init/gs_init.ps
ed4834
@@ -831,12 +831,26 @@ userdict /.currentresourcefile //null put
ed4834
 /.runstring {
ed4834
   0 0 .systemvmstring .systemvmSFD cvx { .runexec } execute0
ed4834
 } bind def
ed4834
+
ed4834
 % Define the procedure that the C code uses to set up for executing
ed4834
 % a string that may be received in pieces.
ed4834
+%
ed4834
+% Immediate evaluation doesn't work on operators (like .needinput)
ed4834
+% so calling .runstringbegin will throw an undefined error if we
ed4834
+% undefined .needinput so it cannot be accessed outside the init
ed4834
+% code. But, we can store the operator in an array, use immediate
ed4834
+% evaluation on the array to get the operator, then undefined the
ed4834
+% array (and because they are both of the same name, the operator
ed4834
+% get undefined too).
ed4834
+% This prevents random Postscript from erroneously calling .needinput
ed4834
+% and forcing the interpreter into an invalid state.
ed4834
+/.needinput
ed4834
+1 .systemvmarray dup 0 /.needinput load put
ed4834
+def
ed4834
 /.runstringbegin {
ed4834
-  1 .systemvmarray dup 0 /.needinput load put cvx	% { .needinput } in systemvm
ed4834
+  1 .systemvmarray dup 0 //.needinput 0 get put cvx	% { .needinput } in systemvm
ed4834
   0 0 .systemvmstring .systemvmSFD cvx .runexec
ed4834
-} bind def
ed4834
+} bind executeonly def
ed4834
 
ed4834
 % Define a special version of runlibfile that aborts on errors.
ed4834
 /runlibfile0
ed4834
@@ -2212,7 +2226,7 @@ SAFER { .setsafeglobal } if
ed4834
   /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
ed4834
   /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
ed4834
   /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice
ed4834
-  /.type /.writecvs /.setSMask /.currentSMask
ed4834
+  /.type /.writecvs /.setSMask /.currentSMask /.needinput
ed4834
 
ed4834
   % Used by a free user in the Library of Congress. Apparently this is used to
ed4834
   % draw a partial page, which is then filled in by the results of a barcode
ed4834
-- 
ed4834
2.17.2
ed4834
ed4834
ed4834
From 34cc326eb2c5695833361887fe0b32e8d987741c Mon Sep 17 00:00:00 2001
ed4834
From: Chris Liddell <chris.liddell@artifex.com>
ed4834
Date: Wed, 10 Oct 2018 15:38:10 +0100
ed4834
Subject: [PATCH 3/3] Bug 699927: don't include operator arrays in execstack
ed4834
 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
---
ed4834
 Resource/Init/gs_init.ps  |  4 ++--
ed4834
 Resource/Init/gs_resmp.ps |  2 +-
ed4834
 psi/int.mak               |  2 +-
ed4834
 psi/interp.c              | 14 +++++++++++---
ed4834
 psi/interp.h              |  2 ++
ed4834
 psi/zcontrol.c            | 13 ++++++++++---
ed4834
 6 files changed, 27 insertions(+), 10 deletions(-)
09061c
ed4834
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
ed4834
index 6a5c1df..5bec480 100644
ed4834
--- a/Resource/Init/gs_init.ps
ed4834
+++ b/Resource/Init/gs_init.ps
ed4834
@@ -2187,7 +2187,7 @@ SAFER { .setsafeglobal } if
ed4834
   %% but can be easily restored (just delete the name from the list in the array). In future
ed4834
   %% we may remove the operator and the code implementation entirely.
ed4834
   [
ed4834
-  /.bitadd /.charboxpath /.cond /.countexecstack /.execstack /.runandhide /.popdevicefilter
ed4834
+  /.bitadd /.charboxpath /.cond /.runandhide /.popdevicefilter
ed4834
   /.execfile /.filenamesplit /.file_name_parent
ed4834
   /.setdefaultmatrix /.isprocfilter /.unread /.psstringencode
ed4834
   /.buildsampledfunction /.isencapfunction /.currentaccuratecurves /.currentcurvejoin /.currentdashadapt /.currentdotlength
ed4834
@@ -2226,7 +2226,7 @@ SAFER { .setsafeglobal } if
ed4834
   /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
ed4834
   /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
ed4834
   /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice
ed4834
-  /.type /.writecvs /.setSMask /.currentSMask /.needinput
ed4834
+  /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack
ed4834
 
ed4834
   % Used by a free user in the Library of Congress. Apparently this is used to
ed4834
   % draw a partial page, which is then filled in by the results of a barcode
ed4834
diff --git a/Resource/Init/gs_resmp.ps b/Resource/Init/gs_resmp.ps
ed4834
index 7cacaf8..9bb4263 100644
ed4834
--- a/Resource/Init/gs_resmp.ps
ed4834
+++ b/Resource/Init/gs_resmp.ps
ed4834
@@ -183,7 +183,7 @@ setpacking
ed4834
   % We don't check them.
ed4834
 
ed4834
   currentglobal //false setglobal                  % <object> bGlobal
ed4834
-  countexecstack array execstack                   % <object> bGlobal [execstack]
ed4834
+  //false .countexecstack array //false .execstack % <object> bGlobal [execstack]
ed4834
   dup //null exch                                  % <object> bGlobal [execstack] null [execstack]
ed4834
   length 3 sub -1 0 {                              % <object> bGlobal [execstack] null i
ed4834
     2 index exch get                               % <object> bGlobal [execstack] null proc
ed4834
diff --git a/psi/int.mak b/psi/int.mak
ed4834
index 5d9b3d5..6ab5bf0 100644
ed4834
--- a/psi/int.mak
ed4834
+++ b/psi/int.mak
ed4834
@@ -323,7 +323,7 @@ $(PSOBJ)zarray.$(OBJ) : $(PSSRC)zarray.c $(OP) $(memory__h)\
ed4834
 
ed4834
 $(PSOBJ)zcontrol.$(OBJ) : $(PSSRC)zcontrol.c $(OP) $(string__h)\
ed4834
  $(estack_h) $(files_h) $(ipacked_h) $(iutil_h) $(store_h) $(stream_h)\
ed4834
- $(INT_MAK) $(MAKEDIRS)
ed4834
+ $(interp_h) $(INT_MAK) $(MAKEDIRS)
ed4834
 	$(PSCC) $(PSO_)zcontrol.$(OBJ) $(C_) $(PSSRC)zcontrol.c
ed4834
 
ed4834
 $(PSOBJ)zdict.$(OBJ) : $(PSSRC)zdict.c $(OP)\
ed4834
diff --git a/psi/interp.c b/psi/interp.c
ed4834
index 3dd5f7a..1dec9b6 100644
ed4834
--- a/psi/interp.c
ed4834
+++ b/psi/interp.c
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 *);
ed4834
@@ -737,7 +736,7 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
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;
ed4834
@@ -746,6 +745,15 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
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
 }
ed4834
@@ -1910,7 +1918,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;
ed4834
diff --git a/psi/interp.h b/psi/interp.h
ed4834
index e9275b9..4f551d1 100644
ed4834
--- a/psi/interp.h
ed4834
+++ b/psi/interp.h
ed4834
@@ -91,5 +91,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 */
ed4834
diff --git a/psi/zcontrol.c b/psi/zcontrol.c
ed4834
index 36da22c..0362cf4 100644
ed4834
--- a/psi/zcontrol.c
ed4834
+++ b/psi/zcontrol.c
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);
ed4834
@@ -787,7 +788,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;
ed4834
@@ -829,6 +830,12 @@ do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1)
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
         }
ed4834
@@ -841,14 +848,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 - */
ed4834
-- 
ed4834
2.17.2
ed4834