blob: a339fa2f333b00a4d7b401ac71d01f4b2010a273 [file] [log] [blame]
Brad Bishopd89cb5f2019-04-10 09:02:41 -04001From 4203e04ef9e6ca22ed68a1ab10a878aa9ceaeedc Mon Sep 17 00:00:00 2001
2From: Ray Johnston <ray.johnston@artifex.com>
3Date: Thu, 14 Feb 2019 10:20:03 -0800
4Subject: [PATCH] Fix bug 700585: Restrict superexec and remove it from
5 internals and gs_cet.ps
6
7Also while changing things, restructure the CETMODE so that it will
8work with -dSAFER. The gs_cet.ps is now run when we are still at save
9level 0 with systemdict writeable. Allows us to undefine .makeoperator
10and .setCPSImode internal operators after CETMODE is handled.
11
12Change previous uses of superexec to using .forceput (with the usual
13.bind executeonly to hide it).
14
15CVE: CVE-2019-3835
16Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git]
17
18Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
19---
20 Resource/Init/gs_cet.ps | 38 ++++++++++++++------------------------
21 Resource/Init/gs_dps1.ps | 2 +-
22 Resource/Init/gs_fonts.ps | 8 ++++----
23 Resource/Init/gs_init.ps | 38 +++++++++++++++++++++++++++-----------
24 Resource/Init/gs_ttf.ps | 8 ++++----
25 Resource/Init/gs_type1.ps | 6 +++---
26 6 files changed, 53 insertions(+), 47 deletions(-)
27
28diff --git a/Resource/Init/gs_cet.ps b/Resource/Init/gs_cet.ps
29index dbc5c4e..3cc6883 100644
30--- a/Resource/Init/gs_cet.ps
31+++ b/Resource/Init/gs_cet.ps
32@@ -1,37 +1,29 @@
33 %!PS
34 % Set defaults for Ghostscript to match Adobe CPSI behaviour for CET
35
36-/.odef { % <name> <proc> odef -
37- 1 index exch .makeoperator def
38-} bind def
39-
40+% skip if we've already run this -- based on fake "product"
41 systemdict /product get (PhotoPRINT SE 5.0v2) readonly eq
42 {
43 (%END GS_CET) .skipeof
44 } if
45
46-% do this in the server level so it is persistent across jobs
47-//true 0 startjob not {
48- (*** Warning: CET startup is not in server default) = flush
49-} if
50+% Note: this must be run at save level 0 and when systemdict is writeable
51+currentglobal //true setglobal
52+systemdict dup dup dup
53+/version (3017.102) readonly .forceput % match CPSI 3017.102
54+/product (PhotoPRINT SE 5.0v2) readonly .forceput % match CPSI 3017.102
55+/revision 0 put % match CPSI 3017.103 Tek shows revision 5
56+/serialnumber dup {233640} readonly .makeoperator .forceput % match CPSI 3017.102 Tek shows serialnumber 1401788461
57+
58+systemdict /.odef { % <name> <proc> odef -
59+ 1 index exch //.makeoperator def
60+} .bind .forceput % this will be undefined at the end
61
62 300 .sethiresscreen % needed for language switch build since it
63 % processes gs_init.ps BEFORE setting the resolution
64
65 0 array 0 setdash % CET 09-08 wants local setdash
66
67-currentglobal //true setglobal
68-
69-{
70- systemdict dup dup dup
71- /version (3017.102) readonly put % match CPSI 3017.102
72- /product (PhotoPRINT SE 5.0v2) readonly put % match CPSI 3017.102
73- /revision 0 put % match CPSI 3017.103 Tek shows revision 5
74- /serialnumber dup {233640} readonly .makeoperator put % match CPSI 3017.102 Tek shows serialnumber 1401788461
75- systemdict /deviceinfo undef % for CET 20-23-1
76-% /UNROLLFORMS true put % CET files do unreasonable things inside forms
77-} 1183615869 internaldict /superexec get exec
78-
79 /UNROLLFORMS true def
80
81 (%.defaultbgrucrproc) cvn { } bind def
82@@ -118,9 +110,7 @@ userdict /.smoothness currentsmoothness put
83 ofnfa
84 } bind def
85
86-currentdict /.odef undef
87-% end of slightly nasty hack to give consistent cluster results
88-
89-//false 0 startjob pop % re-enter encapsulated mode
90+systemdict /.odef .undef
91
92+% end of slightly nasty hack to give consistent cluster results
93 %END GS_CET
94diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps
95index 3d2cf7a..c4fd839 100644
96--- a/Resource/Init/gs_dps1.ps
97+++ b/Resource/Init/gs_dps1.ps
98@@ -89,7 +89,7 @@ level2dict begin
99 % definition, copy it into the local directory.
100 //systemdict /SharedFontDirectory .knownget
101 { 1 index .knownget
102- { //.FontDirectory 2 index 3 -1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly
103+ { //.FontDirectory 2 index 3 -1 roll .forceput } % readonly
104 if
105 }
106 if
107diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps
108index 0562235..f2b4e19 100644
109--- a/Resource/Init/gs_fonts.ps
110+++ b/Resource/Init/gs_fonts.ps
111@@ -519,11 +519,11 @@ buildfontdict 3 /.buildfont3 cvx put
112 % the font in LocalFontDirectory.
113 .currentglobal
114 { //systemdict /LocalFontDirectory .knownget
115- { 2 index 2 index { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly
116+ { 2 index 2 index .forceput } % readonly
117 if
118 }
119 if
120- dup //.FontDirectory 4 -2 roll { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly
121+ dup //.FontDirectory 4 -2 roll .forceput % readonly
122 % If the font originated as a resource, register it.
123 currentfile .currentresourcefile eq { dup .registerfont } if
124 readonly
125@@ -1191,13 +1191,13 @@ $error /SubstituteFont { } put
126 //.FontDirectory 1 index known not {
127 2 dict dup /FontName 3 index put
128 dup /FontType 1 put
129- //.FontDirectory 3 1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly
130+ //.FontDirectory 3 1 roll //.forceput exec % readonly
131 } {
132 pop
133 } ifelse
134 } forall
135 } forall
136- }
137+ } executeonly % hide .forceput
138 FAKEFONTS { exch } if pop def % don't bind, .current/setglobal get redefined
139
140 % Install initial fonts from Fontmap.
141diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
142index 80d9585..0d5c4f7 100644
143--- a/Resource/Init/gs_init.ps
144+++ b/Resource/Init/gs_init.ps
145@@ -2188,9 +2188,6 @@ SAFER { .setsafeglobal } if
146 /.endtransparencygroup % transparency-example.ps
147 /.setdotlength % Bug687720.ps
148 /.sort /.setdebug /.mementolistnewblocks /getenv
149-
150- /.makeoperator /.setCPSImode % gs_cet.ps, this won't work on cluster with -dSAFER
151-
152 /unread
153 ]
154 {systemdict exch .forceundef} forall
155@@ -2270,7 +2267,6 @@ SAFER { .setsafeglobal } if
156
157 % Used by our own test suite files
158 %/.fileposition %image-qa.ps
159- %/.makeoperator /.setCPSImode % gs_cet.ps
160
161 % Either our code uses these in ways which mean they can't be undefined, or they are used directly by
162 % test files/utilities, or engineers expressed a desire to keep them visible.
163@@ -2457,6 +2453,16 @@ end
164 /vmreclaim where
165 { pop NOGC not { 2 .vmreclaim 0 vmreclaim } if
166 } if
167+
168+% Do this before systemdict is locked (see below for additional CETMODE setup using gs_cet.ps)
169+systemdict /CETMODE .knownget {
170+ {
171+ (gs_cet.ps) runlibfile
172+ } if
173+} if
174+systemdict /.makeoperator .undef % must be after gs_cet.ps
175+systemdict /.setCPSImode .undef % must be after gs_cet.ps
176+
177 DELAYBIND not {
178 systemdict /.bindnow .undef % We only need this for DELAYBIND
179 systemdict /.forcecopynew .undef % remove temptation
180@@ -2464,16 +2470,29 @@ DELAYBIND not {
181 systemdict /.forceundef .undef % ditto
182 } if
183
184-% Move superexec to internaldict if superexec is defined.
185-systemdict /superexec .knownget {
186- 1183615869 internaldict /superexec 3 -1 roll put
187- systemdict /superexec .undef
188+% Move superexec to internaldict if superexec is defined. (Level 2 or later)
189+systemdict /superexec known {
190+ % restrict superexec to single known use by PScript5.dll
191+ % We could do this only for SAFER mode, but internaldict and superexec are
192+ % not very well documented, and we don't want them to be used.
193+ 1183615869 internaldict /superexec {
194+ 2 index /Private eq % first check for typical use in PScript5.dll
195+ 1 index length 1 eq and % expected usage is: dict /Private <value> {put} superexec
196+ 1 index 0 get systemdict /put get eq and
197+ {
198+ //superexec exec % the only usage we allow
199+ } {
200+ /superexec load /invalidaccess signalerror
201+ } ifelse
202+ } bind cvx executeonly put
203+ systemdict /superexec .undef % get rid of the dangerous (unrestricted) operator
204 } if
205
206 % Can't remove this one until the last minute :-)
207 DELAYBIND not {
208 systemdict /.undef .undef
209 } if
210+
211 WRITESYSTEMDICT {
212 SAFER {
213 (\n *** WARNING - you have selected SAFER, indicating you want Ghostscript\n) print
214@@ -2500,7 +2519,4 @@ WRITESYSTEMDICT {
215 % be 'true' in some cases.
216 userdict /AGM_preserve_spots //false put
217
218-systemdict /CETMODE .knownget
219-{ { (gs_cet.ps) runlibfile } if } if
220-
221 % The interpreter will run the initial procedure (start).
222diff --git a/Resource/Init/gs_ttf.ps b/Resource/Init/gs_ttf.ps
223index 05943c5..da97afa 100644
224--- a/Resource/Init/gs_ttf.ps
225+++ b/Resource/Init/gs_ttf.ps
226@@ -1421,7 +1421,7 @@ mark
227 TTFDEBUG { (\n1 setting alias: ) print dup ==only
228 ( to be the same as ) print 2 index //== exec } if
229
230- 7 index 2 index 3 -1 roll exch //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse
231+ 7 index 2 index 3 -1 roll exch .forceput
232 } forall
233 pop pop pop
234 }
235@@ -1439,7 +1439,7 @@ mark
236 exch pop
237 TTFDEBUG { (\n2 setting alias: ) print 1 index ==only
238 ( to use glyph index: ) print dup //== exec } if
239- 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse
240+ 5 index 3 1 roll .forceput
241 //false
242 }
243 {
244@@ -1456,7 +1456,7 @@ mark
245 { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) gindex(integer)
246 TTFDEBUG { (\3 nsetting alias: ) print 1 index ==only
247 ( to be index: ) print dup //== exec } if
248- exch pop 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse
249+ exch pop 5 index 3 1 roll .forceput
250 }
251 {
252 pop pop
253@@ -1486,7 +1486,7 @@ mark
254 } ifelse
255 ]
256 TTFDEBUG { (Encoding: ) print dup === flush } if
257-} bind def
258+} .bind executeonly odef % hides .forceput
259
260 % to be removed 9.09......
261 currentdict /postalias undef
262diff --git a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps
263index 96e1ced..61f5269 100644
264--- a/Resource/Init/gs_type1.ps
265+++ b/Resource/Init/gs_type1.ps
266@@ -116,7 +116,7 @@
267 { % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname aglname
268 CFFDEBUG { (\nsetting alias: ) print dup ==only
269 ( to be the same as glyph: ) print 1 index //== exec } if
270- 3 index exch 3 index //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse
271+ 3 index exch 3 index .forceput
272 % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname
273 }
274 {pop} ifelse
275@@ -135,7 +135,7 @@
276 3 1 roll pop pop
277 } if
278 pop
279- dup /.AGLprocessed~GS //true //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse
280+ dup /.AGLprocessed~GS //true .forceput
281 } if
282
283 %% We need to excute the C .buildfont1 in a stopped context so that, if there
284@@ -148,7 +148,7 @@
285 {//.buildfont1} stopped
286 4 3 roll .setglobal
287 {//.buildfont1 $error /errorname get signalerror} if
288- } bind def
289+ } .bind executeonly def % hide .forceput
290
291 % If the diskfont feature isn't included, define a dummy .loadfontdict.
292 /.loadfontdict where
293--
2942.20.1
295