blob: 97c74e7e314018267750f7d021069c9f7391c589 [file] [log] [blame]
Brad Bishopd89cb5f2019-04-10 09:02:41 -04001From 20001d2bdf3cc60e76241a6ae72b1df01c5424c5 Mon Sep 17 00:00:00 2001
2From: Chris Liddell <chris.liddell@artifex.com>
3Date: Thu, 13 Dec 2018 15:28:34 +0000
4Subject: [PATCH 2/7] Any transient procedures that call .force* operators
5
6(i.e. for conditionals or loops) make them executeonly.
7
8CVE: CVE-2019-6116
9Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git]
10
11Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
12---
13 Resource/Init/gs_diskn.ps | 2 +-
14 Resource/Init/gs_dps1.ps | 4 ++--
15 Resource/Init/gs_fntem.ps | 4 ++--
16 Resource/Init/gs_fonts.ps | 12 ++++++------
17 Resource/Init/gs_init.ps | 4 ++--
18 Resource/Init/gs_lev2.ps | 11 ++++++-----
19 Resource/Init/gs_pdfwr.ps | 2 +-
20 Resource/Init/gs_res.ps | 4 ++--
21 Resource/Init/gs_setpd.ps | 2 +-
22 Resource/Init/pdf_base.ps | 13 ++++++++-----
23 Resource/Init/pdf_draw.ps | 16 +++++++++-------
24 Resource/Init/pdf_font.ps | 6 +++---
25 Resource/Init/pdf_main.ps | 4 ++--
26 Resource/Init/pdf_ops.ps | 7 ++++---
27 14 files changed, 49 insertions(+), 42 deletions(-)
28
29diff --git a/Resource/Init/gs_diskn.ps b/Resource/Init/gs_diskn.ps
30index fd694bc..8bf2054 100644
31--- a/Resource/Init/gs_diskn.ps
32+++ b/Resource/Init/gs_diskn.ps
33@@ -51,7 +51,7 @@ systemdict begin
34 mark 5 1 roll ] mark exch { { } forall } forall ]
35 //systemdict /.searchabledevs 2 index .forceput
36 exch .setglobal
37- }
38+ } executeonly
39 if
40 } .bind executeonly odef % must be bound and hidden for .forceput
41
42diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps
43index ec5db61..4fae283 100644
44--- a/Resource/Init/gs_dps1.ps
45+++ b/Resource/Init/gs_dps1.ps
46@@ -78,7 +78,7 @@ level2dict begin
47 .currentglobal
48 { % Current mode is global; delete from local directory too.
49 //systemdict /LocalFontDirectory .knownget
50- { 1 index .forceundef } % LocalFontDirectory is readonly
51+ { 1 index .forceundef } executeonly % LocalFontDirectory is readonly
52 if
53 }
54 { % Current mode is local; if there was a shadowed global
55@@ -126,7 +126,7 @@ level2dict begin
56 }
57 ifelse
58 } forall
59- pop counttomark 2 idiv { .forceundef } repeat pop % readonly
60+ pop counttomark 2 idiv { .forceundef } executeonly repeat pop % readonly
61 }
62 if
63 //SharedFontDirectory exch .forcecopynew pop
64diff --git a/Resource/Init/gs_fntem.ps b/Resource/Init/gs_fntem.ps
65index c1f7651..6eb672a 100644
66--- a/Resource/Init/gs_fntem.ps
67+++ b/Resource/Init/gs_fntem.ps
68@@ -401,12 +401,12 @@ currentdict end def
69 .forceput % FontInfo can be read-only.
70 pop % bool <font>
71 exit
72- } if
73+ } executeonly if
74 dup /FontInfo get % bool <font> <FI>
75 /GlyphNames2Unicode /Unicode /Decoding findresource
76 .forceput % FontInfo can be read-only.
77 exit
78- } loop
79+ } executeonly loop
80 exch setglobal
81 } .bind executeonly odef % must be bound and hidden for .forceput
82
83diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps
84index 803faca..290da0c 100644
85--- a/Resource/Init/gs_fonts.ps
86+++ b/Resource/Init/gs_fonts.ps
87@@ -374,7 +374,7 @@ FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if
88 /.setnativefontmapbuilt { % set whether we've been run
89 dup type /booleantype eq {
90 systemdict exch /.nativefontmapbuilt exch .forceput
91- }
92+ } executeonly
93 {pop}
94 ifelse
95 } .bind executeonly odef
96@@ -1007,11 +1007,11 @@ $error /SubstituteFont { } put
97 { 2 index gcheck currentglobal
98 2 copy eq {
99 pop pop .forceput
100- } {
101+ } executeonly {
102 5 1 roll setglobal
103 dup length string copy
104 .forceput setglobal
105- } ifelse
106+ } executeonly ifelse
107 } .bind executeonly odef % must be bound and hidden for .forceput
108
109 % Attempt to load a font from a file.
110@@ -1084,7 +1084,7 @@ $error /SubstituteFont { } put
111 .FontDirectory 3 index .forceundef % readonly
112 1 index (r) file .loadfont .FontDirectory exch
113 /.setglobal .systemvar exec
114- }
115+ } executeonly
116 { .loadfont .FontDirectory
117 }
118 ifelse
119@@ -1105,7 +1105,7 @@ $error /SubstituteFont { } put
120 dup 3 index .fontknownget
121 { dup /PathLoad 4 index .putgstringcopy
122 4 1 roll pop pop pop //true exit
123- } if
124+ } executeonly if
125
126 % Maybe the file had a different FontName.
127 % See if we can get a FontName from the file, and if so,
128@@ -1134,7 +1134,7 @@ $error /SubstituteFont { } put
129 ifelse % Stack: origfontname fontdict
130 exch pop //true exit
131 % Stack: fontdict
132- }
133+ } executeonly
134 if pop % Stack: origfontname fontdirectory path
135 }
136 if pop pop % Stack: origfontname
137diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
138index d733124..56c0bd2 100644
139--- a/Resource/Init/gs_init.ps
140+++ b/Resource/Init/gs_init.ps
141@@ -2357,7 +2357,7 @@ SAFER { .setsafeglobal } if
142 % Update the copy of the user parameters.
143 mark .currentuserparams counttomark 2 idiv {
144 userparams 3 1 roll .forceput % userparams is read-only
145- } repeat pop
146+ } executeonly repeat pop
147 % Turn on idiom recognition, if available.
148 currentuserparams /IdiomRecognition known {
149 /IdiomRecognition //true .definepsuserparam
150@@ -2376,7 +2376,7 @@ SAFER { .setsafeglobal } if
151 % Remove real system params from pssystemparams.
152 mark .currentsystemparams counttomark 2 idiv {
153 pop pssystemparams exch .forceundef
154- } repeat pop
155+ } executeonly repeat pop
156 } if
157
158 % Set up AlignToPixels :
159diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps
160index 44fe619..0f0d573 100644
161--- a/Resource/Init/gs_lev2.ps
162+++ b/Resource/Init/gs_lev2.ps
163@@ -154,7 +154,8 @@ end
164 % protect top level of parameters that we copied
165 dup type dup /arraytype eq exch /stringtype eq or { readonly } if
166 /userparams .systemvar 3 1 roll .forceput % userparams is read-only
167- } {
168+ } executeonly
169+ {
170 pop pop
171 } ifelse
172 } forall
173@@ -224,7 +225,7 @@ end
174 % protect top level parameters that we copied
175 dup type dup /arraytype eq exch /stringtype eq or { readonly } if
176 //pssystemparams 3 1 roll .forceput % pssystemparams is read-only
177- }
178+ } executeonly
179 { pop pop
180 }
181 ifelse
182@@ -934,7 +935,7 @@ mark
183 dup /PaintProc get
184 1 index /Implementation known not {
185 1 index dup /Implementation //null .forceput readonly pop
186- } if
187+ } executeonly if
188 exec
189 }.bind odef
190
191@@ -958,7 +959,7 @@ mark
192 dup /PaintProc get
193 1 index /Implementation known not {
194 1 index dup /Implementation //null .forceput readonly pop
195- } if
196+ } executeonly if
197 /UNROLLFORMS where {/UNROLLFORMS get}{false}ifelse not
198 %% [CTM] <<Form>> PaintProc .beginform -
199 {
200@@ -1005,7 +1006,7 @@ mark
201 %% Form dictioanry using the /Implementation key).
202 1 dict dup /FormID 4 -1 roll put
203 1 index exch /Implementation exch .forceput readonly pop
204- }
205+ } executeonly
206 ifelse
207 }
208 {
209diff --git a/Resource/Init/gs_pdfwr.ps b/Resource/Init/gs_pdfwr.ps
210index 58e75d3..b425103 100644
211--- a/Resource/Init/gs_pdfwr.ps
212+++ b/Resource/Init/gs_pdfwr.ps
213@@ -650,7 +650,7 @@ currentdict /.pdfmarkparams .undef
214 } ifelse
215 } bind .makeoperator .forceput
216 systemdict /.pdf_hooked_DSC_Creator //true .forceput
217- } if
218+ } executeonly if
219 pop
220 } if
221 } {
222diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps
223index 8eb8bb0..d9b3459 100644
224--- a/Resource/Init/gs_res.ps
225+++ b/Resource/Init/gs_res.ps
226@@ -152,7 +152,7 @@ setglobal
227 % use .forceput / .forcedef later to replace the dummy,
228 % empty .Instances dictionary with the real one later.
229 readonly
230- } {
231+ }{
232 /defineresource cvx /typecheck signaloperror
233 } ifelse
234 } bind executeonly odef
235@@ -424,7 +424,7 @@ status {
236 % As noted above, Category dictionaries are read-only,
237 % so we have to use .forcedef here.
238 /.Instances 1 index .forcedef % Category dict is read-only
239- } if
240+ } executeonly if
241 }
242 { .LocalInstances dup //.emptydict eq
243 { pop 3 dict localinstancedict Category 2 index put
244diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps
245index e22597e..7875d1f 100644
246--- a/Resource/Init/gs_setpd.ps
247+++ b/Resource/Init/gs_setpd.ps
248@@ -634,7 +634,7 @@ NOMEDIAATTRS {
249 SETPDDEBUG { (Rolling back.) = pstack flush } if
250 3 index 2 index 3 -1 roll .forceput
251 4 index 1 index .knownget
252- { 4 index 3 1 roll .forceput }
253+ { 4 index 3 1 roll .forceput } executeonly
254 { 3 index exch .undef }
255 ifelse
256 } bind executeonly odef
257diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps
258index b45e980..7312729 100644
259--- a/Resource/Init/pdf_base.ps
260+++ b/Resource/Init/pdf_base.ps
261@@ -130,26 +130,29 @@ currentdict /num-chars-dict .undef
262
263 /.pdfexectoken { % <count> <opdict> <exectoken> .pdfexectoken ?
264 PDFDEBUG {
265- pdfdict /PDFSTEPcount known not { pdfdict /PDFSTEPcount 1 .forceput } if
266+ pdfdict /PDFSTEPcount known not { pdfdict /PDFSTEPcount 1 .forceput } executeonly if
267 PDFSTEP {
268 pdfdict /PDFtokencount 2 copy .knownget { 1 add } { 1 } ifelse .forceput
269 PDFSTEPcount 1 gt {
270 pdfdict /PDFSTEPcount PDFSTEPcount 1 sub .forceput
271- } {
272+ } executeonly
273+ {
274 dup ==only
275 ( step # ) print PDFtokencount =only
276 ( ? ) print flush 1 //false .outputpage
277 (%stdin) (r) file 255 string readline {
278 token {
279 exch pop pdfdict /PDFSTEPcount 3 -1 roll .forceput
280- } {
281+ } executeonly
282+ {
283 pdfdict /PDFSTEPcount 1 .forceput
284- } ifelse % token
285+ } executeonly ifelse % token
286 } {
287 pop /PDFSTEP //false def % EOF on stdin
288 } ifelse % readline
289 } ifelse % PDFSTEPcount > 1
290- } {
291+ } executeonly
292+ {
293 dup ==only () = flush
294 } ifelse % PDFSTEP
295 } if % PDFDEBUG
296diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
297index 6b0ba93..40c6ac8 100644
298--- a/Resource/Init/pdf_draw.ps
299+++ b/Resource/Init/pdf_draw.ps
300@@ -1118,14 +1118,14 @@ currentdict end readonly def
301 pdfdict /.Qqwarning_issued //true .forceput
302 .setglobal
303 pdfformaterror
304- } ifelse
305+ } executeonly ifelse
306 }
307 {
308 currentglobal pdfdict gcheck .setglobal
309 pdfdict /.Qqwarning_issued //true .forceput
310 .setglobal
311 pdfformaterror
312- } ifelse
313+ } executeonly ifelse
314 end
315 } ifelse
316 } loop
317@@ -1141,14 +1141,14 @@ currentdict end readonly def
318 pdfdict /.Qqwarning_issued //true .forceput
319 .setglobal
320 pdfformaterror
321- } ifelse
322+ } executeonly ifelse
323 }
324 {
325 currentglobal pdfdict gcheck .setglobal
326 pdfdict /.Qqwarning_issued //true .forceput
327 .setglobal
328 pdfformaterror
329- } ifelse
330+ } executeonly ifelse
331 } if
332 pop
333
334@@ -2350,9 +2350,10 @@ currentdict /last-ditch-bpc-csp undef
335 /IncrementAppearanceNumber {
336 pdfdict /AppearanceNumber .knownget {
337 1 add pdfdict /AppearanceNumber 3 -1 roll .forceput
338- }{
339+ } executeonly
340+ {
341 pdfdict /AppearanceNumber 0 .forceput
342- } ifelse
343+ } executeonly ifelse
344 }bind executeonly odef
345
346 /MakeAppearanceName {
347@@ -2510,7 +2511,8 @@ currentdict /last-ditch-bpc-csp undef
348 %% want to preserve it.
349 pdfdict /.PreservePDFForm false .forceput
350 /q cvx /execform cvx 5 -2 roll
351- }{
352+ } executeonly
353+ {
354 /q cvx /PDFexecform cvx 5 -2 roll
355 } ifelse
356
357diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps
358index bea9ea9..4cd62b9 100644
359--- a/Resource/Init/pdf_font.ps
360+++ b/Resource/Init/pdf_font.ps
361@@ -714,7 +714,7 @@ currentdict end readonly def
362 pop pop pop
363 currentdict /.stackdepth .forceundef
364 currentdict /.dstackdepth .forceundef
365- }
366+ } executeonly
367 {pop pop pop}
368 ifelse
369
370@@ -1232,7 +1232,7 @@ currentdict /eexec_pdf_param_dict .undef
371 (\n **** Warning: Type 3 glyph has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n)
372 pdfformatwarning
373 pdfdict /.Qqwarning_issued //true .forceput
374- } if
375+ } executeonly if
376 Q
377 } repeat
378 Q
379@@ -2016,7 +2016,7 @@ currentdict /CMap_read_dict undef
380 /CIDFallBack /CIDFont findresource
381 } if
382 exit
383- } if
384+ } executeonly if
385 } if
386 } if
387
388diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps
389index 00da47a..37e69b3 100644
390--- a/Resource/Init/pdf_main.ps
391+++ b/Resource/Init/pdf_main.ps
392@@ -2701,14 +2701,14 @@ currentdict /PDF2PS_matrix_key undef
393 pdfdict /.Qqwarning_issued //true .forceput
394 .setglobal
395 pdfformaterror
396- } ifelse
397+ } executeonly ifelse
398 }
399 {
400 currentglobal pdfdict gcheck .setglobal
401 pdfdict /.Qqwarning_issued //true .forceput
402 .setglobal
403 pdfformaterror
404- } ifelse
405+ } executeonly ifelse
406 } if
407 } if
408 pop
409diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps
410index 8672d61..aa09641 100644
411--- a/Resource/Init/pdf_ops.ps
412+++ b/Resource/Init/pdf_ops.ps
413@@ -184,14 +184,14 @@ currentdict /gput_always_allow .undef
414 pdfdict /.Qqwarning_issued //true .forceput
415 .setglobal
416 pdfformaterror
417- } ifelse
418+ } executeonly ifelse
419 }
420 {
421 currentglobal pdfdict gcheck .setglobal
422 pdfdict /.Qqwarning_issued //true .forceput
423 .setglobal
424 pdfformaterror
425- } ifelse
426+ } executeonly ifelse
427 } if
428 } bind executeonly odef
429
430@@ -439,7 +439,8 @@ currentdict /gput_always_allow .undef
431 dup type /booleantype eq {
432 .currentSMask type /dicttype eq {
433 .currentSMask /Processed 2 index .forceput
434- } {
435+ } executeonly
436+ {
437 .setSMask
438 }ifelse
439 }{
440--
4412.18.1
442