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

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