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

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