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

483aca
From 8d19fdf63f91f50466b08f23e2d93d37a4c5ea0b Mon Sep 17 00:00:00 2001
483aca
From: Ken Sharp <ken.sharp@artifex.com>
483aca
Date: Mon, 15 Oct 2018 11:28:28 +0100
483aca
Subject: [PATCH] Make .forceput unavailable from '.policyprocs' helper
483aca
 dictionary
483aca
483aca
Bug #69963 "1Policy is a dangerous operator, any callers should be odef"
483aca
483aca
Leaving the .policyprocs dictionary with a procedure which is a simple
483aca
wrapper for .forceput effectively leaves .forceput available.
483aca
483aca
It seems that the only reason to have .policyprocs is to minimise the
483aca
code in .applypolicies, so we can remove the dictionary and put the
483aca
code straight into .applypolicies, which we can then bind and make
483aca
executeonly, which hides the .forceput. Also, since we don't need
483aca
.applypolicies after startup, we can undefine that from systemdict too.
483aca
483aca
While we're here, review all the uses of .force* to make certain that
483aca
there are no other similar cases. This showed a few places where we
483aca
hadn't made a function executeonly, so do that too. Its probably not
483aca
required, since I'm reasonably sure its impossible to load those
483aca
functions as packed arrays (they are all defined as operators), but lets
483aca
have a belt and braces approach, the additional time cost is negligible.
483aca
---
483aca
 Resource/Init/gs_diskn.ps |   2 +-
483aca
 Resource/Init/gs_dps.ps   |   2 +-
483aca
 Resource/Init/gs_epsf.ps  |   2 +-
483aca
 Resource/Init/gs_fonts.ps |   4 +-
483aca
 Resource/Init/gs_init.ps  |   2 +-
483aca
 Resource/Init/gs_setpd.ps | 100 ++++++++++++++++++++------------------
483aca
 6 files changed, 58 insertions(+), 54 deletions(-)
483aca
483aca
diff --git a/Resource/Init/gs_diskn.ps b/Resource/Init/gs_diskn.ps
483aca
index 26ec0b5..fd694bc 100644
483aca
--- a/Resource/Init/gs_diskn.ps
483aca
+++ b/Resource/Init/gs_diskn.ps
483aca
@@ -61,7 +61,7 @@ systemdict begin
483aca
   % doesn't get run enough to justify the complication
483aca
   //.putdevparams
483aca
   //systemdict /.searchabledevs .forceundef
483aca
-} .bind odef % must be bound and hidden for .forceundef
483aca
+} .bind executeonly odef % must be bound and hidden for .forceundef
483aca
 
483aca
 % ------ extend filenameforall to handle wildcards in %dev% part of pattern -------%
483aca
 /filenameforall {
483aca
diff --git a/Resource/Init/gs_dps.ps b/Resource/Init/gs_dps.ps
483aca
index daf7b0f..00c14d5 100644
483aca
--- a/Resource/Init/gs_dps.ps
483aca
+++ b/Resource/Init/gs_dps.ps
483aca
@@ -124,7 +124,7 @@
483aca
   /savedinitialgstate .systemvar setgstate gsave
483aca
                 % Wrap up.
483aca
   end .setglobal
483aca
-} odef
483aca
+} bind executeonly odef
483aca
 
483aca
 % Check whether an object is a procedure.
483aca
 /.proccheck {			% <obj> .proccheck <bool>
483aca
diff --git a/Resource/Init/gs_epsf.ps b/Resource/Init/gs_epsf.ps
483aca
index e4037d9..2d0f677 100644
483aca
--- a/Resource/Init/gs_epsf.ps
483aca
+++ b/Resource/Init/gs_epsf.ps
483aca
@@ -31,7 +31,7 @@
483aca
 /EPSBoundingBoxState 5 def
483aca
 /EPSBoundingBoxSetState {
483aca
   //systemdict /EPSBoundingBoxState 3 -1 roll .forceput
483aca
-} .bind odef % .forceput must be bound and hidden
483aca
+} .bind executeonly odef % .forceput must be bound and hidden
483aca
 
483aca
 % Parse 4 numbers for a bounding box
483aca
 /EPSBoundingBoxParse { % (llx lly urx ury) -- llx lly urx ury true OR false
483aca
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps
483aca
index 7a57366..052a191 100644
483aca
--- a/Resource/Init/gs_fonts.ps
483aca
+++ b/Resource/Init/gs_fonts.ps
483aca
@@ -583,7 +583,7 @@ buildfontdict 3 /.buildfont3 cvx put
483aca
 } bind def
483aca
 /.setloadingfont {
483aca
    //systemdict /.loadingfont 3 -1 roll .forceput
483aca
-} .bind odef % .forceput must be bound and hidden
483aca
+} .bind executeonly odef % .forceput must be bound and hidden
483aca
 /.loadfont
483aca
  {              % Some buggy fonts leave extra junk on the stack,
483aca
                 % so we have to make a closure that records the stack depth
483aca
@@ -1012,7 +1012,7 @@ $error /SubstituteFont { } put
483aca
     dup length string copy
483aca
     .forceput setglobal
483aca
   } ifelse
483aca
-} .bind odef % must be bound and hidden for .forceput
483aca
+} .bind executeonly odef % must be bound and hidden for .forceput
483aca
 
483aca
 % Attempt to load a font from a file.
483aca
 /.tryloadfont {         % <fontname> .tryloadfont <font> true
483aca
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
483aca
index 2114a2a..0b900e6 100644
483aca
--- a/Resource/Init/gs_init.ps
483aca
+++ b/Resource/Init/gs_init.ps
483aca
@@ -2244,7 +2244,7 @@ SAFER { .setsafeglobal } if
483aca
   /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
483aca
   /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
483aca
   /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice
483aca
-  /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack
483aca
+  /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack /.applypolicies
483aca
 
483aca
   % Used by a free user in the Library of Congress. Apparently this is used to
483aca
   % draw a partial page, which is then filled in by the results of a barcode
483aca
diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps
483aca
index fab8b84..71eb622 100644
483aca
--- a/Resource/Init/gs_setpd.ps
483aca
+++ b/Resource/Init/gs_setpd.ps
483aca
@@ -609,6 +609,23 @@ NOMEDIAATTRS {
483aca
 % and we replace the key in the <merged> dictionary with its prior value
483aca
 % (or remove it if it had no prior value).
483aca
 
483aca
+% These procedures are called with the following on the stack:
483aca
+%   <orig> <merged> <failed> <Policies> <key> <policy>
483aca
+% They are expected to consume the top 2 operands.
483aca
+% NOTE: we currently treat all values other than 0, 1, or 7 (for PageSize)
483aca
+% the same as 0, i.e., we signal an error.
483aca
+/0Policy {		% Set errorinfo and signal a configurationerror.
483aca
+  NOMEDIAATTRS {
483aca
+    % NOMEDIAATTRS means that the default policy is 7...
483aca
+    pop 2 index exch 7 put
483aca
+  } {
483aca
+    pop dup 4 index exch get 2 array astore
483aca
+    $error /errorinfo 3 -1 roll put
483aca
+    cleartomark
483aca
+    /setpagedevice .systemvar /configurationerror signalerror
483aca
+  } ifelse
483aca
+} bind executeonly odef
483aca
+
483aca
 % Making this an operator means we can properly hide
483aca
 % the contents - specifically .forceput
483aca
 /1Policy
483aca
@@ -617,59 +634,46 @@ NOMEDIAATTRS {
483aca
   SETPDDEBUG { (Rolling back.) = pstack flush } if
483aca
   3 index 2 index 3 -1 roll .forceput
483aca
   4 index 1 index .knownget
483aca
-   { 4 index 3 1 roll .forceput }
483aca
-   { 3 index exch .undef }
483aca
+  { 4 index 3 1 roll .forceput }
483aca
+  { 3 index exch .undef }
483aca
   ifelse
483aca
 } bind executeonly odef
483aca
 
483aca
-/.policyprocs mark
483aca
-% These procedures are called with the following on the stack:
483aca
-%   <orig> <merged> <failed> <Policies> <key> <policy>
483aca
-% They are expected to consume the top 2 operands.
483aca
-% NOTE: we currently treat all values other than 0, 1, or 7 (for PageSize)
483aca
-% the same as 0, i.e., we signal an error.
483aca
-%
483aca
-% M. Sweet, Easy Software Products:
483aca
-%
483aca
-% Define NOMEDIAATTRS to turn off the default (but unimplementable) media
483aca
-% selection policies for setpagedevice.  This is used by CUPS to support
483aca
-% the standard Adobe media attributes.
483aca
-  0 {		% Set errorinfo and signal a configurationerror.
483aca
-      NOMEDIAATTRS {
483aca
-        % NOMEDIAATTRS means that the default policy is 7...
483aca
-        pop 2 index exch 7 put
483aca
-      } {
483aca
-        pop dup 4 index exch get 2 array astore
483aca
-        $error /errorinfo 3 -1 roll put
483aca
-        cleartomark
483aca
-        /setpagedevice .systemvar /configurationerror signalerror
483aca
-      } ifelse
483aca
-  } bind
483aca
-  1 /1Policy load
483aca
-  7 {		% For PageSize only, just impose the request.
483aca
-        1 index /PageSize eq
483aca
-         { pop pop 1 index /PageSize 7 put }
483aca
-         { .policyprocs 0 get exec }
483aca
-        ifelse
483aca
-  } bind
483aca
-.dicttomark readonly def
483aca
-currentdict /1Policy undef
483aca
+/7Policy {		% For PageSize only, just impose the request.
483aca
+  1 index /PageSize eq
483aca
+  { pop pop 1 index /PageSize 7 put }
483aca
+  { .policyprocs 0 get exec }
483aca
+  ifelse
483aca
+} bind executeonly odef
483aca
 
483aca
 /.applypolicies		% <orig> <merged> <failed> .applypolicies
483aca
                         %   <orig> <merged'> <failed'>
483aca
- { 1 index /Policies get 1 index
483aca
-    { type /integertype eq
483aca
-       { pop		% already processed
483aca
-       }
483aca
-       { 2 copy .knownget not { 1 index /PolicyNotFound get } if
483aca
-                        % Stack: <orig> <merged> <failed> <Policies> <key>
483aca
-                        %   <policy>
483aca
-         .policyprocs 1 index .knownget not { .policyprocs 0 get } if exec
483aca
-       }
483aca
-      ifelse
483aca
-    }
483aca
-   forall pop
483aca
- } bind def
483aca
+{
483aca
+  1 index /Policies get 1 index
483aca
+  { type /integertype eq
483aca
+     {
483aca
+       pop		% already processed
483aca
+     }{
483aca
+       2 copy .knownget not { 1 index /PolicyNotFound get } if
483aca
+                      % Stack: <orig> <merged> <failed> <Policies> <key>
483aca
+                      %   <policy>
483aca
+        dup 1 eq {
483aca
+          1Policy
483aca
+        }{
483aca
+          dup 7 eq {
483aca
+            7Policy
483aca
+          }{
483aca
+            0Policy
483aca
+          } ifelse
483aca
+        } ifelse
483aca
+     } ifelse
483aca
+  }
483aca
+  forall pop
483aca
+} bind executeonly odef
483aca
+
483aca
+currentdict /0Policy undef
483aca
+currentdict /1Policy undef
483aca
+currentdict /7Policy undef
483aca
 
483aca
 % Prepare to present parameters to the device, by spreading them onto the
483aca
 % operand stack and removing any that shouldn't be presented.
483aca
@@ -1012,7 +1016,7 @@ SETPDDEBUG { (Installing.) = pstack flush } if
483aca
     .postinstall
483aca
   } ifelse
483aca
   setglobal           % return to original VM allocation mode
483aca
-} odef
483aca
+} bind executeonly odef
483aca
 
483aca
 % We break out the code after calling the Install procedure into a
483aca
 % separate procedure, since it is executed even if Install causes an error.
483aca
-- 
483aca
2.17.2
483aca