[oe-commits] [openembedded-core] 03/14: ghostscript: fix CVE-2018-18284

git at git.openembedded.org git at git.openembedded.org
Mon Nov 5 09:00:32 UTC 2018


This is an automated email from the git hooks/post-receive script.

rpurdie pushed a commit to branch master-next
in repository openembedded-core.

commit e46bdf96db7082c7e1800f64fda859c35d22c723
Author: Hongxu Jia <hongxu.jia at windriver.com>
AuthorDate: Mon Nov 5 16:03:37 2018 +0800

    ghostscript: fix CVE-2018-18284
    
    Artifex Ghostscript 9.25 and earlier allows attackers to bypass a
    sandbox protection mechanism via vectors involving the 1Policy
    operator.
    
    Signed-off-by: Hongxu Jia <hongxu.jia at windriver.com>
    Signed-off-by: Richard Purdie <richard.purdie at linuxfoundation.org>
---
 ...put-unavailable-from-.policyprocs-helper-.patch | 245 +++++++++++++++++++++
 .../ghostscript/ghostscript_9.25.bb                |   1 +
 2 files changed, 246 insertions(+)

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

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Openembedded-commits mailing list