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

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