Blob Blame History Raw
From: Ken Sharp <ken.sharp@artifex.com>
Date: Tue, 25 Apr 2017 16:08:26 +0000 (+0100)
Subject: PS interpreter - remove superexec from systemdict

PS interpreter - remove superexec from systemdict

This looks like bit rot, superexec was meant to have been undefined from
systemdict, and moved to internaldict, but the code only executed if
superexec was defined in the current dictionary. It seems that at some
time in the past the order of execution was changed in such a way that
the current dictionary at that point was no longer systemdict.

So instead of checking currentdict, explicitly check systemdict.

This means changing our gs_cet.ps file which we use for the Quality
Logic CET (Command Emulation Test) suite so that it can find superexec
and use it to set up our environment in a specific fashion, to prevent
spurious differences when running the tests.

If sueperexec isn't available when we run the CET tests we'll get an
error, which sounds like a good idea, hopefully we'll notice that.

https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=8556b698892e4706aa0b9d996bec82fed645eaa5

From: Ken Sharp <ken.sharp@artifex.com>
Date: Sat, 17 Jun 2017 13:27:06 +0000 (+0100)
Subject: PS interpreter - fix use of superexec with DELAYBIND

PS interpreter - fix use of superexec with DELAYBIND

Commit 8556b698892e4706aa0b9d996bec82fed645eaa5 removed superexec from
systemdict, leaving it in internaldict, where it should be. However,
if we run with DELAYBIND then by the time we come to bind the procedures
which use superexec the definition in systemdict is gone.

Technically this shouldn't be a problem, as we should be using the version
in internaldict. But if we do that, without DELAYBIND the internaldict
definition isn't present, because we haven't copied it yet....

So now we look for the presence of superexec in systemdict and use that
one if its present, otherwise we assume its in internaldict and use
that instead.

Unfortunately the use of DELAYBIND interferes with the cluster testing
causing thousands of files to fail. I've run a random selection of them
locally in a normal setup and they work, I guess we'll just have to
hope for the best and fix any problems as they are reported.

https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=c294b131ea270cea5d66c9b0a6ea61d3a69a20a0

From: Ray Johnston <ray.johnston@artifex.com>
Date: Wed, 29 Aug 2018 16:30:19 +0000 (-0700)
Subject: Fix for security issues found during internal security audit

Fix for security issues found during internal security audit

While most of the invocations of .forceput and related operators were
"protected" by being within "executeonly" procedures, several had crept
in that did not make sure that the operator was hidden in a procedure
that could not be read.

https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=c98cb5237c983e363fe05757b2639eab550499e8

From: Nancy Durgin <nancy.durgin@artifex.com>
Date: Tue, 13 Nov 2018 22:23:41 +0000 (-0800)
Subject: Undefine some level2-related operators

Undefine some level2-related operators

These are only a partial set.  Undefine them in both the level2dict and
systemdict.  They are undef'd in gs_init.ps because they are used outside
the scope of just gs_lev2.ps

      /.execform1
      /.getdevparams
      /.setuserparams2
      /.startjob
      /.checkFilePermitparams
      /.checksetparams
      /.copyparam
      /.setpagesize

Rename .dict1 to .pair2dict and use immediate reference.

Undef these at end of gs_lev2.ps (should never make it into systemdict):
      /.pair2dict
      /.checkprocesscomment

https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=fe4c47d8e25d6366ecbb5ff487348148b908a89e
---

diff -up ghostscript-9.07/Resource/Init/gs_cet.ps.cve-2019-3839-part1 ghostscript-9.07/Resource/Init/gs_cet.ps
--- ghostscript-9.07/Resource/Init/gs_cet.ps.cve-2019-3839-part1	2019-02-27 07:32:54.469246630 +0100
+++ ghostscript-9.07/Resource/Init/gs_cet.ps	2019-02-27 07:35:20.114364074 +0100
@@ -20,7 +20,7 @@ currentglobal //true setglobal
   /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
-} superexec
+} 1183615869 internaldict /superexec get exec
 
 { } bind dup
 setblackgeneration
diff -up ghostscript-9.07/Resource/Init/gs_dps1.ps.cve-2019-3839-part1 ghostscript-9.07/Resource/Init/gs_dps1.ps
--- ghostscript-9.07/Resource/Init/gs_dps1.ps.cve-2019-3839-part1	2019-02-27 07:44:11.371487238 +0100
+++ ghostscript-9.07/Resource/Init/gs_dps1.ps	2019-02-27 07:44:56.922883917 +0100
@@ -86,7 +86,7 @@ level2dict begin
                 % definition, copy it into the local directory.
       //systemdict /SharedFontDirectory .knownget
        { 1 index .knownget
-          { .FontDirectory 2 index 3 -1 roll { put } //superexec } % readonly
+          { .FontDirectory 2 index 3 -1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly
          if
        }
       if
diff -up ghostscript-9.07/Resource/Init/gs_fonts.ps.cve-2019-3839-part1 ghostscript-9.07/Resource/Init/gs_fonts.ps
--- ghostscript-9.07/Resource/Init/gs_fonts.ps.cve-2019-3839-part1	2019-02-27 07:45:31.420426999 +0100
+++ ghostscript-9.07/Resource/Init/gs_fonts.ps	2019-02-27 07:47:16.440036018 +0100
@@ -501,11 +501,11 @@ buildfontdict 3 /.buildfont3 cvx put
                 % the font in LocalFontDirectory.
    .currentglobal
     { //systemdict /LocalFontDirectory .knownget
-       { 2 index 2 index { .growput } //superexec }	% readonly
+       { 2 index 2 index { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse }  % readonly
       if
     }
    if
-   dup .FontDirectory 4 -2 roll { .growput } //superexec	% readonly
+   dup .FontDirectory 4 -2 roll { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse     % readonly
                 % If the font originated as a resource, register it.
    currentfile .currentresourcefile eq { dup .registerfont } if
    readonly
@@ -1149,7 +1149,7 @@ currentdict /.putgstringcopy .forceundef
         .FontDirectory 1 index known not {
           2 dict dup /FontName 3 index put
           dup /FontType 1 put
-          .FontDirectory 3 1 roll { put } //superexec	% readonly
+          .FontDirectory 3 1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse   % readonly
         } {
           pop
         } ifelse
diff -up ghostscript-9.07/Resource/Init/gs_init.ps.cve-2019-3839-part1 ghostscript-9.07/Resource/Init/gs_init.ps
--- ghostscript-9.07/Resource/Init/gs_init.ps.cve-2019-3839-part1	2019-02-27 07:36:30.132459049 +0100
+++ ghostscript-9.07/Resource/Init/gs_init.ps	2019-02-27 12:11:55.798721262 +0100
@@ -2111,139 +2111,157 @@ currentdict /tempfilepaths undef
 SAFER { .setsafe } if
 
 /SAFERUndefinePostScriptOperators {
-[
-% Used by our own test suite files
-/.pushpdf14devicefilter    % transparency-example.ps
-/.poppdf14devicefilter     % transparency-example.ps
-/.setopacityalpha          % transparency-example.ps
-/.setshapealpha            % transparency-example.ps
-/.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
+  [
+  % Used by our own test suite files
+  /.pushpdf14devicefilter    % transparency-example.ps
+  /.poppdf14devicefilter     % transparency-example.ps
+  /.setopacityalpha          % transparency-example.ps
+  /.setshapealpha            % transparency-example.ps
+  /.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
 
-//systemdict /SAFERUndefinePostScriptOperators .forceundef
-}bind def
+  //systemdict /SAFERUndefinePostScriptOperators .forceundef
+} .bind executeonly def % must be bound and hidden for .forceundef
 
 /UndefinePostScriptOperators {
 
-%% This list is of Display PostScript operators. We believe that Display PostScript
-%% was never fully implemented and the only known user, GNUStep, is no longer
-%% using it. So lets remove it.
-[
-/condition /currentcontext /detach /.fork /join /.localfork /lock /monitor /notify
-/wait /yield /.currentscreenphase /.setscreenphase /.image2 /eoviewclip /initviewclip
-/viewclip /viewclippath /defineusername
-%% NeXT DPS extensions
-/currentalpha /setalpha /.alphaimage /composite /compositerect /dissolve /sizeimagebox /.sizeimageparams
-]
-{systemdict exch .forceundef} forall
-
-%% This list is of operators which no longer appear to be used, and which we do not believe
-%% to have any real use. For now we will undefine the operstors so they cannot easily be used
-%% but can be easily restored (just delete the name from the list in the array). In future
-%% we may remove the operator and the code implementation entirely.
-[
-/.bitadd /.charboxpath /.cond /.runandhide /.popdevicefilter
-/.execfile /.filenamesplit /.file_name_parent
-/.setdefaultmatrix /.isprocfilter /.unread /.psstringencode
-/.buildsampledfunction /.isencapfunction /.currentaccuratecurves /.currentcurvejoin /.currentdashadapt /.currentdotlength
-/.currentlimitclamp /.dotorientation /.setaccuratecurves /.setcurvejoin /.setdashadapt /.setdotorientation
-/.setlimitclamp /.currentscreenlevels /.dashpath /.pathbbox /.identeq /.identne /.tokenexec /.forgetsave /.pantonecallback
-
-%% Used by our own test suite files
-%%/.setdotlength % Bug687720.ps
-]
-{systemdict exch .forceundef} forall
-
-%% This list of operators are used internally by various parts of the Ghostscript startup code.
-%% Since each operator is a potential security vulnerability, and any operator listed here
-%% is not required once the initislisation is complete and functions are bound, we undefine
-%% the ones that aren't needed at runtime.
-[
-/.callinstall /.callbeginpage /.callendpage
-/.currentstackprotect /.setstackprotect /.errorexec /.finderrorobject /.installsystemnames /.bosobject /.fontbbox
-/.type1execchar /.type2execchar /.type42execchar /.setweightvector /.getuseciecolor /processcolors /.includecolorspace
-/.execn /.instopped /.stop /.stopped /.setcolorrendering /.setdevicecolorrendering /.buildcolorrendering1 /.builddevicecolorrendering1
-/.TransformPQR_scale_WB0 /.TransformPQR_scale_WB1 /.TransformPQR_scale_WB2 /.currentoverprintmode /.copydevice2
-/.devicename /.doneshowpage /.getbitsrect /.getdevice /.getdefaultdevice /.getdeviceparams /.gethardwareparams
-/makewordimagedevice /.outputpage /.putdeviceparams /.setdevice /.currentshowpagecount
-/.setpagedevice /.currentpagedevice /.knownundef /.setmaxlength /.rectappend /.initialize_dsc_parser /.parse_dsc_comments
-/.fillCIDMap /.fillIdentityCIDMap /.buildcmap /.filenamelistseparator /.libfile /.getfilename
-/.file_name_combine /.file_name_is_absolute /.file_name_separator /.file_name_directory_separator /.file_name_current /.filename
-/.peekstring /.writecvp /.subfiledecode /.setupUnicodeDecoder /.jbig2makeglobalctx /.registerfont /.parsecff
-/.getshowoperator /.getnativefonts /.beginform /.endform /.get_form_id /.repeatform /.reusablestream /.rsdparams
-/.buildfunction /.currentfilladjust2 /.setfilladjust2 /.sethpglpathmode /.currenthpglpathmode
-/.currenthalftone /.sethalftone5 /.image1 /.imagemask1 /.image3 /.image4
-/.getiodevice /.getdevparms /.putdevparams /.bbox_transform /.matchmedia /.matchpagesize /.defaultpapersize
-/.oserrno /.setoserrno /.oserrorstring /.getCPSImode
-/.getscanconverter /.setscanconverter /.type1encrypt /.type1decrypt/.languagelevel /.setlanguagelevel /.eqproc /.fillpage /.buildpattern1 /.saslprep
-/.buildshading1 /.buildshading2 /.buildshading3 /.buildshading4 /.buildshading5 /.buildshading6 /.buildshading7 /.buildshadingpattern
-/.shfill /.argindex /.bytestring /.namestring /.stringbreak /.stringmatch /.globalvmarray /.globalvmdict /.globalvmpackedarray /.globalvmstring
-/.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 /.currentoutputdevice
-/.type /.writecvs /.setSMask /.currentSMask /.needinput /.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
-% scanner and SQL database lookup. Its not clear to us exactly why this needs to be
-% done as a partial page, but its easiest to restore the operator, and it seems like
-% its a reasonably safe operator to restore, for the *very* few devices on which
-% it will have any effect. Currently this uses the 'sync_outptu' device method
-% to transfer the partial page, in future we may use a spec_op instead.
-%/flushpage
-
-% 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.
-%
-%/currentdevice /.sort /.buildfont0 /.buildfont1 /.buildfont2 /.buildfont3 /.buildfont4 /.buildfont9 /.buildfont10 /.buildfont11
-%/.buildfont32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors
-%/currentdevice  /.quit /.setuseciecolor /.needinput /.setoverprintmode /.special_op /.dicttomark /.knownget
-%/.FAPIavailable /.FAPIpassfont /.FAPIrebuildfont /.FAPIBuildGlyph /.FAPIBuildChar /.FAPIBuildGlyph9
-%/.tempfile /.numicc_components /.set_outputintent  /.max /.min /.vmreclaim /.getpath /.setglobal
-%/.setdebug /.mementolistnewblocks /getenv
-]
-{systemdict exch .forceundef} forall
+  %% This list is of Display PostScript operators. We believe that Display PostScript
+  %% was never fully implemented and the only known user, GNUStep, is no longer
+  %% using it. So lets remove it.
+  [
+  /condition /currentcontext /detach /.fork /join /.localfork /lock /monitor /notify
+  /wait /yield /.currentscreenphase /.setscreenphase /.image2 /eoviewclip /initviewclip
+  /viewclip /viewclippath /defineusername
+  %% NeXT DPS extensions
+  /currentalpha /setalpha /.alphaimage /composite /compositerect /dissolve /sizeimagebox /.sizeimageparams
+  ]
+  {systemdict exch .forceundef} forall
+
+  %% This list is of operators which no longer appear to be used, and which we do not believe
+  %% to have any real use. For now we will undefine the operstors so they cannot easily be used
+  %% but can be easily restored (just delete the name from the list in the array). In future
+  %% we may remove the operator and the code implementation entirely.
+  [
+  /.bitadd /.charboxpath /.cond /.runandhide /.popdevicefilter
+  /.execfile /.filenamesplit /.file_name_parent
+  /.setdefaultmatrix /.isprocfilter /.unread /.psstringencode
+  /.buildsampledfunction /.isencapfunction /.currentaccuratecurves /.currentcurvejoin /.currentdashadapt /.currentdotlength
+  /.currentlimitclamp /.dotorientation /.setaccuratecurves /.setcurvejoin /.setdashadapt /.setdotorientation
+  /.setlimitclamp /.currentscreenlevels /.dashpath /.pathbbox /.identeq /.identne /.tokenexec /.forgetsave /.pantonecallback
+
+  %% Used by our own test suite files
+  %%/.setdotlength % Bug687720.ps
+  ]
+  {systemdict exch .forceundef} forall
+
+  %% This list of operators are used internally by various parts of the Ghostscript startup code.
+  %% Since each operator is a potential security vulnerability, and any operator listed here
+  %% is not required once the initislisation is complete and functions are bound, we undefine
+  %% the ones that aren't needed at runtime.
+  [
+  /.callinstall /.callbeginpage /.callendpage
+  /.currentstackprotect /.setstackprotect /.errorexec /.finderrorobject /.installsystemnames /.bosobject /.fontbbox
+  /.type1execchar /.type2execchar /.type42execchar /.setweightvector /.getuseciecolor /processcolors /.includecolorspace
+  /.execn /.instopped /.stop /.stopped /.setcolorrendering /.setdevicecolorrendering /.buildcolorrendering1 /.builddevicecolorrendering1
+  /.TransformPQR_scale_WB0 /.TransformPQR_scale_WB1 /.TransformPQR_scale_WB2 /.currentoverprintmode /.copydevice2
+  /.devicename /.doneshowpage /.getbitsrect /.getdevice /.getdefaultdevice /.getdeviceparams /.gethardwareparams
+  /makewordimagedevice /.outputpage /.putdeviceparams /.setdevice /.currentshowpagecount
+  /.setpagedevice /.currentpagedevice /.knownundef /.setmaxlength /.rectappend /.initialize_dsc_parser /.parse_dsc_comments
+  /.fillCIDMap /.fillIdentityCIDMap /.buildcmap /.filenamelistseparator /.libfile /.getfilename
+  /.file_name_combine /.file_name_is_absolute /.file_name_separator /.file_name_directory_separator /.file_name_current /.filename
+  /.peekstring /.writecvp /.subfiledecode /.setupUnicodeDecoder /.jbig2makeglobalctx /.registerfont /.parsecff
+  /.getshowoperator /.getnativefonts /.beginform /.endform /.get_form_id /.repeatform /.reusablestream /.rsdparams
+  /.buildfunction /.currentfilladjust2 /.setfilladjust2 /.sethpglpathmode /.currenthpglpathmode
+  /.currenthalftone /.sethalftone5 /.image1 /.imagemask1 /.image3 /.image4
+  /.getiodevice /.getdevparms /.putdevparams /.bbox_transform /.matchmedia /.matchpagesize /.defaultpapersize
+  /.oserrno /.setoserrno /.oserrorstring /.getCPSImode
+  /.getscanconverter /.setscanconverter /.type1encrypt /.type1decrypt/.languagelevel /.setlanguagelevel /.eqproc /.fillpage /.buildpattern1 /.saslprep
+  /.buildshading1 /.buildshading2 /.buildshading3 /.buildshading4 /.buildshading5 /.buildshading6 /.buildshading7 /.buildshadingpattern
+  /.shfill /.argindex /.bytestring /.namestring /.stringbreak /.stringmatch /.globalvmarray /.globalvmdict /.globalvmpackedarray /.globalvmstring
+  /.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 /.currentoutputdevice
+  /.type /.writecvs /.setSMask /.currentSMask /.needinput /.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
+  % scanner and SQL database lookup. Its not clear to us exactly why this needs to be
+  % done as a partial page, but its easiest to restore the operator, and it seems like
+  % its a reasonably safe operator to restore, for the *very* few devices on which
+  % it will have any effect. Currently this uses the 'sync_outptu' device method
+  % to transfer the partial page, in future we may use a spec_op instead.
+  %/flushpage
+
+  % 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.
+  %
+  %/currentdevice /.sort /.buildfont0 /.buildfont1 /.buildfont2 /.buildfont3 /.buildfont4 /.buildfont9 /.buildfont10 /.buildfont11
+  %/.buildfont32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors
+  %/currentdevice  /.quit /.setuseciecolor /.needinput /.setoverprintmode /.special_op /.dicttomark /.knownget
+  %/.FAPIavailable /.FAPIpassfont /.FAPIrebuildfont /.FAPIBuildGlyph /.FAPIBuildChar /.FAPIBuildGlyph9
+  %/.tempfile /.numicc_components /.set_outputintent  /.max /.min /.vmreclaim /.getpath /.setglobal
+  %/.setdebug /.mementolistnewblocks /getenv
+  ]
+  {systemdict exch .forceundef} forall
+
+  % level 2 operators, undefine from both systemdict and level2dict
+  [
+      /.execform1
+      /.getdevparams
+      /.setuserparams2
+      /.startjob
+      /.checkFilePermitparams
+      /.checksetparams
+      /.copyparam
+      /.setpagesize
+
+% Couldn't figure out how to do these yet
+%      /.checkparamtype
+%      /.startnewjob
+  ]
+  dup {level2dict exch .forceundef} forall
+  {systemdict exch .forceundef} forall
 
-//systemdict /UndefinePostScriptOperators .forceundef
-} bind def
+  //systemdict /UndefinePostScriptOperators .forceundef
+} .bind executeonly def % must be bound and hidden for .forceundef
 
 /UndefinePDFOperators {
-%% This list of operators are used internally by various parts of the Ghostscript PDF interpreter.
-%% Since each operator is a potential security vulnerability, and any operator listed here
-%% is not required once the initislisation is complete and functions are bound, we undefine
-%% the ones that aren't needed at runtime.
-[
-/.pdfawidthshow /.pdfwidthshow
-/.setfillcolor /.setfillcolorspace /.setstrokecolor /.setstrokecolorspace /.currentrenderingintent /.setrenderingintent
-/.currenttextrenderingmode /.settextspacing /.currenttextspacing /.settextleading /.currenttextleading
-/.settextrise /.currenttextrise /.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling
-/.settextlinematrix /.currenttextlinematrix /.currenttextmatrix /.settextmatrix /.currentblendmode
-/.currentopacityalpha /.currentshapealpha /.currenttextknockout
-/.pushextendedgstate /.popextendedgstate /.begintransparencytextgroup
-/.endtransparencytextgroup /.begintransparencymaskgroup /.begintransparencymaskimage /.endtransparencymask /.image3x
-/.abortpdf14devicefilter /.pdfinkpath /.pdfFormName /.setstrokeconstantalpha
-/.setfillconstantalpha /.setalphaisshape /.currentalphaisshape
-/.settextspacing /.currenttextspacing /.settextleading /.currenttextleading /.settextrise /.currenttextrise
-/.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling
-
-% undefining these causes errors/incorrect output
-%/.settextrenderingmode /.setblendmode /.begintransparencygroup /.settextknockout /check_r6_password /.setstrokeoverprint /.setfilloverprint
-%/.currentstrokeoverprint /.currentfilloverprint /.currentfillconstantalpha /.currentstrokeconstantalpha
-]
-{systemdict exch .forceundef} forall
-//systemdict /UndefinePDFOperators .forceundef
-} bind def
+  %% This list of operators are used internally by various parts of the Ghostscript PDF interpreter.
+  %% Since each operator is a potential security vulnerability, and any operator listed here
+  %% is not required once the initislisation is complete and functions are bound, we undefine
+  %% the ones that aren't needed at runtime.
+  [
+  /.pdfawidthshow /.pdfwidthshow
+  /.setfillcolor /.setfillcolorspace /.setstrokecolor /.setstrokecolorspace /.currentrenderingintent /.setrenderingintent
+  /.currenttextrenderingmode /.settextspacing /.currenttextspacing /.settextleading /.currenttextleading
+  /.settextrise /.currenttextrise /.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling
+  /.settextlinematrix /.currenttextlinematrix /.currenttextmatrix /.settextmatrix /.currentblendmode
+  /.currentopacityalpha /.currentshapealpha /.currenttextknockout
+  /.pushextendedgstate /.popextendedgstate /.begintransparencytextgroup
+  /.endtransparencytextgroup /.begintransparencymaskgroup /.begintransparencymaskimage /.endtransparencymask /.image3x
+  /.abortpdf14devicefilter /.pdfinkpath /.pdfFormName /.setstrokeconstantalpha
+  /.setfillconstantalpha /.setalphaisshape /.currentalphaisshape
+  /.settextspacing /.currenttextspacing /.settextleading /.currenttextleading /.settextrise /.currenttextrise
+  /.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling
+
+  % undefining these causes errors/incorrect output
+  %/.settextrenderingmode /.setblendmode /.begintransparencygroup /.settextknockout /check_r6_password /.setstrokeoverprint /.setfilloverprint
+  %/.currentstrokeoverprint /.currentfilloverprint /.currentfillconstantalpha /.currentstrokeconstantalpha
+  ]
+  {systemdict exch .forceundef} forall
+  //systemdict /UndefinePDFOperators .forceundef
+} .bind executeonly def % must be bound and hidden for .forceundef
 
 % If we delayed binding, make it possible to do it later.
 /.bindnow {
@@ -2386,9 +2404,9 @@ DELAYBIND not {
   systemdict /.forceundef .undef	% ditto
 } if
 % Move superexec to internaldict if superexec is defined.
-currentdict /superexec .knownget {
+systemdict /superexec .knownget {
   1183615869 internaldict /superexec 3 -1 roll put
-  currentdict /superexec .undef
+  systemdict /superexec .undef
 } if
 
 %% Can't remove this one until the last minute :-)
diff -up ghostscript-9.07/Resource/Init/gs_lev2.ps.cve-2019-3839-part1 ghostscript-9.07/Resource/Init/gs_lev2.ps
--- ghostscript-9.07/Resource/Init/gs_lev2.ps.cve-2019-3839-part1	2019-02-27 12:14:12.442926989 +0100
+++ ghostscript-9.07/Resource/Init/gs_lev2.ps	2019-02-27 12:54:04.228526320 +0100
@@ -64,7 +64,7 @@ level2dict begin
       pop
     } ifelse pop pop
   } forall pop pop
-} .bind def	% not odef, shouldn't reset stacks
+} .bind odef
 
 % currentuser/systemparams creates and returns a dictionary in the
 % current VM.  The easiest way to make this work is to copy any composite
@@ -101,7 +101,7 @@ level2dict begin
     1 index length string exch .setglobal
     copy exch not { readonly } if
   } if
-} .bind def
+} .bind odef
 
 % Some user parameters are managed entirely at the PostScript level.
 % We take care of that here.
@@ -343,13 +343,13 @@ end
   } ifelse
 } .bind def
 /ProcessComment //null .definepsuserparam
-psuserparams /ProcessComment {.checkprocesscomment} put
+psuserparams /ProcessComment {//.checkprocesscomment exec} put
 (%ProcessComment) cvn {
   /ProcessComment getuserparam
   dup //null eq { pop pop pop } { exec } ifelse
 } bind def
 /ProcessDSCComment //null .definepsuserparam
-psuserparams /ProcessDSCComment {.checkprocesscomment} put
+psuserparams /ProcessDSCComment {//.checkprocesscomment exec} put
 /.loadingfont //false def
 (%ProcessDSCComment) cvn {
   /ProcessDSCComment getuserparam
@@ -554,7 +554,8 @@ end		% serverdict
 % Note that statusdict must be allocated in local VM.
 % We don't bother with many of these yet.
 
-/.dict1 { exch mark 3 1 roll .dicttomark } bind def
+% convenience function to make a dictionary from an object and a key
+/.pair2dict { exch mark 3 1 roll .dicttomark } bind def
 
 currentglobal //false setglobal 25 dict exch setglobal begin
 currentsystemparams
@@ -567,11 +568,11 @@ systemdict /buildtime dup load put
 /checkpassword { .checkpassword 0 gt } bind def
 dup /DoStartPage known
  { /dostartpage { /DoStartPage getsystemparam } bind def
-   /setdostartpage { /DoStartPage .dict1 setsystemparams } bind def
+   /setdostartpage { /DoStartPage //.pair2dict exec setsystemparams } bind def
  } if
 dup /StartupMode known
  { /dosysstart { /StartupMode getsystemparam 0 ne } bind def
-   /setdosysstart { { 1 } { 0 } ifelse /StartupMode .dict1 setsystemparams } bind def
+   /setdosysstart { { 1 } { 0 } ifelse /StartupMode //.pair2dict exec setsystemparams } bind def
  } if
 %****** Setting jobname is supposed to set userparams.JobName, too.
 /jobname { /JobName getuserparam } bind def
@@ -579,7 +580,7 @@ dup /StartupMode known
 /ramsize { /RamSize getsystemparam } bind def
 /realformat 1 index /RealFormat get def
 dup /PrinterName known
- { /setprintername { /PrinterName .dict1 setsystemparams } bind def
+ { /setprintername { /PrinterName //.pair2dict exec setsystemparams } bind def
  } if
 /printername
  { currentsystemparams /PrinterName .knownget not { () } if exch copy
@@ -614,12 +615,12 @@ currentuserparams /WaitTimeout known
    .dicttomark setpagedevice
    /WaitTimeout exch mark /JobTimeout 5 2 roll .dicttomark setsystemparams
  } bind def
-/.setpagesize { 2 array astore /PageSize .dict1 setpagedevice } bind def
-/setduplexmode { /Duplex .dict1 setpagedevice } bind def
+/.setpagesize { 2 array astore /PageSize //.pair2dict exec setpagedevice } bind def
+/setduplexmode { /Duplex //.pair2dict exec setpagedevice } bind def
 /setmargins
- { exch 2 array astore /Margins .dict1 setpagedevice
+ { exch 2 array astore /Margins //.pair2dict exec setpagedevice
  } bind def
-/setpagemargin { 0 2 array astore /PageOffset .dict1 setpagedevice } bind def
+/setpagemargin { 0 2 array astore /PageOffset //.pair2dict exec setpagedevice } bind def
 /setpageparams
  { mark /PageSize 6 -2 roll
    4 index 1 and ORIENT1 { 1 } { 0 } ifelse ne { exch } if 2 array astore
@@ -628,7 +629,7 @@ currentuserparams /WaitTimeout known
    .dicttomark setpagedevice
  } bind def
 /setresolution
- { dup 2 array astore /HWResolution .dict1 setpagedevice
+ { dup 2 array astore /HWResolution //.pair2dict exec setpagedevice
  } bind def
 %END PAGEDEVICE
 
@@ -1076,3 +1077,10 @@ def
 %END TN 5044 psuedo-ops
 
 end				% level2dict
+
+% undefine things defined in this file and not referenced elsewhere
+[
+    /.checkprocesscomment
+    /.pair2dict
+]
+{level2dict exch .forceundef} forall
diff -up ghostscript-9.07/Resource/Init/gs_type1.ps.cve-2019-3839-part1 ghostscript-9.07/Resource/Init/gs_type1.ps
--- ghostscript-9.07/Resource/Init/gs_type1.ps.cve-2019-3839-part1	2019-02-27 09:28:21.973106203 +0100
+++ ghostscript-9.07/Resource/Init/gs_type1.ps	2019-02-27 10:30:47.260979260 +0100
@@ -66,11 +66,11 @@
        2 index 1 index known {
          pop pop
        } {
-         3 1 roll get //.growput superexec dup dup
+         3 1 roll get //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse dup dup
        } ifelse
      } {
        2 index 1 index known {
-         exch 3 1 roll get //.growput superexec dup dup
+         exch 3 1 roll get //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse dup dup
        } {
          pop pop
        } ifelse