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

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