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

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