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

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