| From 4203e04ef9e6ca22ed68a1ab10a878aa9ceaeedc Mon Sep 17 00:00:00 2001 |
| From: Ray Johnston <ray.johnston@artifex.com> |
| Date: Thu, 14 Feb 2019 10:20:03 -0800 |
| Subject: [PATCH] Fix bug 700585: Restrict superexec and remove it from |
| internals and gs_cet.ps |
| |
| Also while changing things, restructure the CETMODE so that it will |
| work with -dSAFER. The gs_cet.ps is now run when we are still at save |
| level 0 with systemdict writeable. Allows us to undefine .makeoperator |
| and .setCPSImode internal operators after CETMODE is handled. |
| |
| Change previous uses of superexec to using .forceput (with the usual |
| .bind executeonly to hide it). |
| |
| CVE: CVE-2019-3835 |
| Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git] |
| |
| Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> |
| --- |
| Resource/Init/gs_cet.ps | 38 ++++++++++++++------------------------ |
| Resource/Init/gs_dps1.ps | 2 +- |
| Resource/Init/gs_fonts.ps | 8 ++++---- |
| Resource/Init/gs_init.ps | 38 +++++++++++++++++++++++++++----------- |
| Resource/Init/gs_ttf.ps | 8 ++++---- |
| Resource/Init/gs_type1.ps | 6 +++--- |
| 6 files changed, 53 insertions(+), 47 deletions(-) |
| |
| diff --git a/Resource/Init/gs_cet.ps b/Resource/Init/gs_cet.ps |
| index dbc5c4e..3cc6883 100644 |
| --- a/Resource/Init/gs_cet.ps |
| +++ b/Resource/Init/gs_cet.ps |
| @@ -1,37 +1,29 @@ |
| %!PS |
| % Set defaults for Ghostscript to match Adobe CPSI behaviour for CET |
| |
| -/.odef { % <name> <proc> odef - |
| - 1 index exch .makeoperator def |
| -} bind def |
| - |
| +% skip if we've already run this -- based on fake "product" |
| systemdict /product get (PhotoPRINT SE 5.0v2) readonly eq |
| { |
| (%END GS_CET) .skipeof |
| } if |
| |
| -% do this in the server level so it is persistent across jobs |
| -//true 0 startjob not { |
| - (*** Warning: CET startup is not in server default) = flush |
| -} if |
| +% Note: this must be run at save level 0 and when systemdict is writeable |
| +currentglobal //true setglobal |
| +systemdict dup dup dup |
| +/version (3017.102) readonly .forceput % match CPSI 3017.102 |
| +/product (PhotoPRINT SE 5.0v2) readonly .forceput % match CPSI 3017.102 |
| +/revision 0 put % match CPSI 3017.103 Tek shows revision 5 |
| +/serialnumber dup {233640} readonly .makeoperator .forceput % match CPSI 3017.102 Tek shows serialnumber 1401788461 |
| + |
| +systemdict /.odef { % <name> <proc> odef - |
| + 1 index exch //.makeoperator def |
| +} .bind .forceput % this will be undefined at the end |
| |
| 300 .sethiresscreen % needed for language switch build since it |
| % processes gs_init.ps BEFORE setting the resolution |
| |
| 0 array 0 setdash % CET 09-08 wants local setdash |
| |
| -currentglobal //true setglobal |
| - |
| -{ |
| - systemdict dup dup dup |
| - /version (3017.102) readonly put % match CPSI 3017.102 |
| - /product (PhotoPRINT SE 5.0v2) readonly put % match CPSI 3017.102 |
| - /revision 0 put % match CPSI 3017.103 Tek shows revision 5 |
| - /serialnumber dup {233640} readonly .makeoperator put % match CPSI 3017.102 Tek shows serialnumber 1401788461 |
| - systemdict /deviceinfo undef % for CET 20-23-1 |
| -% /UNROLLFORMS true put % CET files do unreasonable things inside forms |
| -} 1183615869 internaldict /superexec get exec |
| - |
| /UNROLLFORMS true def |
| |
| (%.defaultbgrucrproc) cvn { } bind def |
| @@ -118,9 +110,7 @@ userdict /.smoothness currentsmoothness put |
| ofnfa |
| } bind def |
| |
| -currentdict /.odef undef |
| -% end of slightly nasty hack to give consistent cluster results |
| - |
| -//false 0 startjob pop % re-enter encapsulated mode |
| +systemdict /.odef .undef |
| |
| +% end of slightly nasty hack to give consistent cluster results |
| %END GS_CET |
| diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps |
| index 3d2cf7a..c4fd839 100644 |
| --- a/Resource/Init/gs_dps1.ps |
| +++ b/Resource/Init/gs_dps1.ps |
| @@ -89,7 +89,7 @@ level2dict begin |
| % definition, copy it into the local directory. |
| //systemdict /SharedFontDirectory .knownget |
| { 1 index .knownget |
| - { //.FontDirectory 2 index 3 -1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly |
| + { //.FontDirectory 2 index 3 -1 roll .forceput } % readonly |
| if |
| } |
| if |
| diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps |
| index 0562235..f2b4e19 100644 |
| --- a/Resource/Init/gs_fonts.ps |
| +++ b/Resource/Init/gs_fonts.ps |
| @@ -519,11 +519,11 @@ buildfontdict 3 /.buildfont3 cvx put |
| % the font in LocalFontDirectory. |
| .currentglobal |
| { //systemdict /LocalFontDirectory .knownget |
| - { 2 index 2 index { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly |
| + { 2 index 2 index .forceput } % readonly |
| if |
| } |
| if |
| - dup //.FontDirectory 4 -2 roll { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly |
| + dup //.FontDirectory 4 -2 roll .forceput % readonly |
| % If the font originated as a resource, register it. |
| currentfile .currentresourcefile eq { dup .registerfont } if |
| readonly |
| @@ -1191,13 +1191,13 @@ $error /SubstituteFont { } put |
| //.FontDirectory 1 index known not { |
| 2 dict dup /FontName 3 index put |
| dup /FontType 1 put |
| - //.FontDirectory 3 1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly |
| + //.FontDirectory 3 1 roll //.forceput exec % readonly |
| } { |
| pop |
| } ifelse |
| } forall |
| } forall |
| - } |
| + } executeonly % hide .forceput |
| FAKEFONTS { exch } if pop def % don't bind, .current/setglobal get redefined |
| |
| % Install initial fonts from Fontmap. |
| diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
| index 80d9585..0d5c4f7 100644 |
| --- a/Resource/Init/gs_init.ps |
| +++ b/Resource/Init/gs_init.ps |
| @@ -2188,9 +2188,6 @@ SAFER { .setsafeglobal } if |
| /.endtransparencygroup % transparency-example.ps |
| /.setdotlength % Bug687720.ps |
| /.sort /.setdebug /.mementolistnewblocks /getenv |
| - |
| - /.makeoperator /.setCPSImode % gs_cet.ps, this won't work on cluster with -dSAFER |
| - |
| /unread |
| ] |
| {systemdict exch .forceundef} forall |
| @@ -2270,7 +2267,6 @@ SAFER { .setsafeglobal } if |
| |
| % Used by our own test suite files |
| %/.fileposition %image-qa.ps |
| - %/.makeoperator /.setCPSImode % gs_cet.ps |
| |
| % Either our code uses these in ways which mean they can't be undefined, or they are used directly by |
| % test files/utilities, or engineers expressed a desire to keep them visible. |
| @@ -2457,6 +2453,16 @@ end |
| /vmreclaim where |
| { pop NOGC not { 2 .vmreclaim 0 vmreclaim } if |
| } if |
| + |
| +% Do this before systemdict is locked (see below for additional CETMODE setup using gs_cet.ps) |
| +systemdict /CETMODE .knownget { |
| + { |
| + (gs_cet.ps) runlibfile |
| + } if |
| +} if |
| +systemdict /.makeoperator .undef % must be after gs_cet.ps |
| +systemdict /.setCPSImode .undef % must be after gs_cet.ps |
| + |
| DELAYBIND not { |
| systemdict /.bindnow .undef % We only need this for DELAYBIND |
| systemdict /.forcecopynew .undef % remove temptation |
| @@ -2464,16 +2470,29 @@ DELAYBIND not { |
| systemdict /.forceundef .undef % ditto |
| } if |
| |
| -% Move superexec to internaldict if superexec is defined. |
| -systemdict /superexec .knownget { |
| - 1183615869 internaldict /superexec 3 -1 roll put |
| - systemdict /superexec .undef |
| +% Move superexec to internaldict if superexec is defined. (Level 2 or later) |
| +systemdict /superexec known { |
| + % restrict superexec to single known use by PScript5.dll |
| + % We could do this only for SAFER mode, but internaldict and superexec are |
| + % not very well documented, and we don't want them to be used. |
| + 1183615869 internaldict /superexec { |
| + 2 index /Private eq % first check for typical use in PScript5.dll |
| + 1 index length 1 eq and % expected usage is: dict /Private <value> {put} superexec |
| + 1 index 0 get systemdict /put get eq and |
| + { |
| + //superexec exec % the only usage we allow |
| + } { |
| + /superexec load /invalidaccess signalerror |
| + } ifelse |
| + } bind cvx executeonly put |
| + systemdict /superexec .undef % get rid of the dangerous (unrestricted) operator |
| } if |
| |
| % Can't remove this one until the last minute :-) |
| DELAYBIND not { |
| systemdict /.undef .undef |
| } if |
| + |
| WRITESYSTEMDICT { |
| SAFER { |
| (\n *** WARNING - you have selected SAFER, indicating you want Ghostscript\n) print |
| @@ -2500,7 +2519,4 @@ WRITESYSTEMDICT { |
| % be 'true' in some cases. |
| userdict /AGM_preserve_spots //false put |
| |
| -systemdict /CETMODE .knownget |
| -{ { (gs_cet.ps) runlibfile } if } if |
| - |
| % The interpreter will run the initial procedure (start). |
| diff --git a/Resource/Init/gs_ttf.ps b/Resource/Init/gs_ttf.ps |
| index 05943c5..da97afa 100644 |
| --- a/Resource/Init/gs_ttf.ps |
| +++ b/Resource/Init/gs_ttf.ps |
| @@ -1421,7 +1421,7 @@ mark |
| TTFDEBUG { (\n1 setting alias: ) print dup ==only |
| ( to be the same as ) print 2 index //== exec } if |
| |
| - 7 index 2 index 3 -1 roll exch //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse |
| + 7 index 2 index 3 -1 roll exch .forceput |
| } forall |
| pop pop pop |
| } |
| @@ -1439,7 +1439,7 @@ mark |
| exch pop |
| TTFDEBUG { (\n2 setting alias: ) print 1 index ==only |
| ( to use glyph index: ) print dup //== exec } if |
| - 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse |
| + 5 index 3 1 roll .forceput |
| //false |
| } |
| { |
| @@ -1456,7 +1456,7 @@ mark |
| { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) gindex(integer) |
| TTFDEBUG { (\3 nsetting alias: ) print 1 index ==only |
| ( to be index: ) print dup //== exec } if |
| - exch pop 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse |
| + exch pop 5 index 3 1 roll .forceput |
| } |
| { |
| pop pop |
| @@ -1486,7 +1486,7 @@ mark |
| } ifelse |
| ] |
| TTFDEBUG { (Encoding: ) print dup === flush } if |
| -} bind def |
| +} .bind executeonly odef % hides .forceput |
| |
| % to be removed 9.09...... |
| currentdict /postalias undef |
| diff --git a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps |
| index 96e1ced..61f5269 100644 |
| --- a/Resource/Init/gs_type1.ps |
| +++ b/Resource/Init/gs_type1.ps |
| @@ -116,7 +116,7 @@ |
| { % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname aglname |
| CFFDEBUG { (\nsetting alias: ) print dup ==only |
| ( to be the same as glyph: ) print 1 index //== exec } if |
| - 3 index exch 3 index //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse |
| + 3 index exch 3 index .forceput |
| % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname |
| } |
| {pop} ifelse |
| @@ -135,7 +135,7 @@ |
| 3 1 roll pop pop |
| } if |
| pop |
| - dup /.AGLprocessed~GS //true //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse |
| + dup /.AGLprocessed~GS //true .forceput |
| } if |
| |
| %% We need to excute the C .buildfont1 in a stopped context so that, if there |
| @@ -148,7 +148,7 @@ |
| {//.buildfont1} stopped |
| 4 3 roll .setglobal |
| {//.buildfont1 $error /errorname get signalerror} if |
| - } bind def |
| + } .bind executeonly def % hide .forceput |
| |
| % If the diskfont feature isn't included, define a dummy .loadfontdict. |
| /.loadfontdict where |
| -- |
| 2.20.1 |
| |