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

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