1 From 0661bf23a5be32973682e17afed4a2f23a8214ba Mon Sep 17 00:00:00 2001
2 From: Chris Liddell <chris.liddell@artifex.com>
3 Date: Sat, 29 Sep 2018 15:34:55 +0100
4 Subject: [PATCH 2/5] Bug 699816: Improve hiding of security critical custom
7 Make procedures that use .forceput/.forcedef/.forceundef into operators.
9 The result of this is that errors get reported against the "top" operator,
10 rather than the "called" operator within the procedure.
18 If 'myop' throws an error, the error handler will be passed the 'myop'
19 operator. Promoting 'myproc' to a operator means the error handler will be
23 Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git]
24 Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
26 Resource/Init/gs_diskn.ps | 2 +-
27 Resource/Init/gs_dps.ps | 2 +-
28 Resource/Init/gs_fntem.ps | 2 +-
29 Resource/Init/gs_fonts.ps | 10 +++++-----
30 Resource/Init/gs_lev2.ps | 13 +++++++++----
31 Resource/Init/gs_pdfwr.ps | 2 +-
32 Resource/Init/gs_setpd.ps | 25 +++++++++++++++++--------
33 Resource/Init/gs_typ32.ps | 14 +++++++++-----
34 Resource/Init/gs_type1.ps | 2 +-
35 Resource/Init/pdf_base.ps | 2 +-
36 Resource/Init/pdf_draw.ps | 10 +++++-----
37 Resource/Init/pdf_font.ps | 8 ++++----
38 Resource/Init/pdf_main.ps | 4 ++--
39 Resource/Init/pdf_ops.ps | 8 ++++----
40 14 files changed, 61 insertions(+), 43 deletions(-)
42 diff --git a/Resource/Init/gs_diskn.ps b/Resource/Init/gs_diskn.ps
43 index 5540715..26ec0b5 100644
44 --- a/Resource/Init/gs_diskn.ps
45 +++ b/Resource/Init/gs_diskn.ps
46 @@ -53,7 +53,7 @@ systemdict begin
50 -} .bind executeonly def % must be bound and hidden for .forceput
51 +} .bind executeonly odef % must be bound and hidden for .forceput
53 % Modify .putdevparams to force regeneration of .searchabledevs list
55 diff --git a/Resource/Init/gs_dps.ps b/Resource/Init/gs_dps.ps
56 index cad7056..daf7b0f 100644
57 --- a/Resource/Init/gs_dps.ps
58 +++ b/Resource/Init/gs_dps.ps
60 % Save a copy of the initial gstate.
61 //systemdict /savedinitialgstate gstate readonly .forceput
63 -} .bind executeonly def % must be bound and hidden for .forceput
64 +} .bind executeonly odef % must be bound and hidden for .forceput
66 % Initialize local dictionaries and gstate when creating a new context.
67 % Note that until this completes, we are in the anomalous situation of
68 diff --git a/Resource/Init/gs_fntem.ps b/Resource/Init/gs_fntem.ps
69 index 3ceee18..c1f7651 100644
70 --- a/Resource/Init/gs_fntem.ps
71 +++ b/Resource/Init/gs_fntem.ps
72 @@ -408,7 +408,7 @@ currentdict end def
76 -} .bind executeonly def % must be bound and hidden for .forceput
77 +} .bind executeonly odef % must be bound and hidden for .forceput
79 currentdict end /ProcSet defineresource pop
81 diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps
82 index 45b6613..89c3ab7 100644
83 --- a/Resource/Init/gs_fonts.ps
84 +++ b/Resource/Init/gs_fonts.ps
85 @@ -377,8 +377,8 @@ FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if
89 -} .bind executeonly def
90 -systemdict /NONATIVEFONTMAP known //.setnativefontmapbuilt exec
91 +} .bind executeonly odef
92 +systemdict /NONATIVEFONTMAP known .setnativefontmapbuilt
93 /.buildnativefontmap { % - .buildnativefontmap <bool>
94 systemdict /.nativefontmapbuilt .knownget not
96 @@ -419,7 +419,7 @@ systemdict /NONATIVEFONTMAP known //.setnativefontmapbuilt exec
99 % record that we've been run
100 - //true //.setnativefontmapbuilt exec
101 + //true .setnativefontmapbuilt
104 currentdict /.setnativefontmapbuilt .forceundef
105 @@ -1103,7 +1103,7 @@ $error /SubstituteFont { } put
107 % Check to make sure the font was actually loaded.
108 dup 3 index .fontknownget
109 - { dup /PathLoad 4 index //.putgstringcopy exec
110 + { dup /PathLoad 4 index .putgstringcopy
111 4 1 roll pop pop pop //true exit
114 @@ -1115,7 +1115,7 @@ $error /SubstituteFont { } put
115 { % Stack: origfontname fontdirectory path filefontname
116 2 index 1 index .fontknownget
117 { % Yes. Stack: origfontname fontdirectory path filefontname fontdict
118 - dup 4 -1 roll /PathLoad exch //.putgstringcopy exec
119 + dup 4 -1 roll /PathLoad exch .putgstringcopy
120 % Stack: origfontname fontdirectory filefontname fontdict
122 % Stack: origfontname filefontname fontdict
123 diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps
124 index eee0b9f..a8ed892 100644
125 --- a/Resource/Init/gs_lev2.ps
126 +++ b/Resource/Init/gs_lev2.ps
127 @@ -163,10 +163,11 @@ end
128 % Set them again to the new values. From here on, we are safe,
129 % since a context switch will consult userparams.
131 -} .bind executeonly def % must be bound and hidden for .forceput
132 +} .bind executeonly odef % must be bound and hidden for .forceput
134 /setuserparams { % <dict> setuserparams -
136 + {.setuserparams2} stopped
137 + {/setuserparams load $error /errorname get signalerror} if
139 % Initialize user parameters managed here.
140 /JobName () .definepsuserparam
141 @@ -415,7 +416,9 @@ psuserparams /ProcessDSCComment {.checkprocesscomment} put
143 % VMReclaim and VMThreshold are user parameters.
144 /setvmthreshold { % <int> setvmthreshold -
145 - mark /VMThreshold 2 .argindex .dicttomark .setuserparams2 pop
146 + mark /VMThreshold 2 .argindex .dicttomark {.setuserparams2} stopped
147 + {pop /setvmthreshold load $error /errorname get signalerror}
150 /vmreclaim { % <int> vmreclaim -
152 @@ -427,7 +430,9 @@ psuserparams /ProcessDSCComment {.checkprocesscomment} put
155 % VMReclaim userparam controls enable/disable GC
156 - mark /VMReclaim 2 index .dicttomark .setuserparams2 pop
157 + mark /VMReclaim 2 index .dicttomark {.setuserparams2} stopped
158 + {pop /vmreclaim load $error /errorname get signalerror}
163 diff --git a/Resource/Init/gs_pdfwr.ps b/Resource/Init/gs_pdfwr.ps
164 index fb1c419..58e75d3 100644
165 --- a/Resource/Init/gs_pdfwr.ps
166 +++ b/Resource/Init/gs_pdfwr.ps
167 @@ -660,7 +660,7 @@ currentdict /.pdfmarkparams .undef
171 -} .bind executeonly def % must be bound and hidden for .forceput
172 +} .bind executeonly odef % must be bound and hidden for .forceput
174 % Use the DSC processing hook to pass DSC comments to the driver.
175 % We use a pseudo-parameter named DSC whose value is an array:
176 diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps
177 index 8fa7c51..afb4ffa 100644
178 --- a/Resource/Init/gs_setpd.ps
179 +++ b/Resource/Init/gs_setpd.ps
180 @@ -608,6 +608,20 @@ NOMEDIAATTRS {
181 % in the <failed> dictionary with the policy value,
182 % and we replace the key in the <merged> dictionary with its prior value
183 % (or remove it if it had no prior value).
185 +% Making this an operator means we can properly hide
186 +% the contents - specifically .forceput
189 + % Roll back the failed request to its previous status.
190 + SETPDDEBUG { (Rolling back.) = pstack flush } if
191 + 3 index 2 index 3 -1 roll .forceput
192 + 4 index 1 index .knownget
193 + { 4 index 3 1 roll .forceput }
194 + { 3 index exch .undef }
196 +} bind executeonly odef
199 % These procedures are called with the following on the stack:
200 % <orig> <merged> <failed> <Policies> <key> <policy>
201 @@ -631,14 +645,7 @@ NOMEDIAATTRS {
202 /setpagedevice .systemvar /configurationerror signalerror
205 - 1 { % Roll back the failed request to its previous status.
206 -SETPDDEBUG { (Rolling back.) = pstack flush } if
207 - 3 index 2 index 3 -1 roll .forceput
208 - 4 index 1 index .knownget
209 - { 4 index 3 1 roll .forceput }
210 - { 3 index exch .undef }
212 - } .bind executeonly % must be bound and hidden for .forceput
214 7 { % For PageSize only, just impose the request.
216 { pop pop 1 index /PageSize 7 put }
217 @@ -646,6 +653,8 @@ SETPDDEBUG { (Rolling back.) = pstack flush } if
220 .dicttomark readonly def
221 +currentdict /1Policy undef
223 /.applypolicies % <orig> <merged> <failed> .applypolicies
224 % <orig> <merged'> <failed'>
225 { 1 index /Policies get 1 index
226 diff --git a/Resource/Init/gs_typ32.ps b/Resource/Init/gs_typ32.ps
227 index b6600b0..9150f71 100644
228 --- a/Resource/Init/gs_typ32.ps
229 +++ b/Resource/Init/gs_typ32.ps
230 @@ -79,15 +79,19 @@ systemdict /.removeglyphs .undef
231 .dicttomark /ProcSet defineresource pop
233 /.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse
236 -4 % CIDFontType 4 = FontType 32
237 -{ dup /FontType 32 .forceput
240 + dup /FontType 32 .forceput
241 dup /CharStrings 20 dict .forceput
242 1 index exch .buildfont32 exch pop
243 -} .bind executeonly def % must be bound and hidden for .forceput
244 +} .bind executeonly odef
248 +4 /CIDFontType4 load def % CIDFontType 4 = FontType 32
251 +currentdict /CIDFontType4 .forceundef
253 % Define the BuildGlyph procedure.
254 % Since Type 32 fonts are indexed by CID, there is no BuildChar procedure.
255 diff --git a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps
256 index efdae48..2935d9c 100644
257 --- a/Resource/Init/gs_type1.ps
258 +++ b/Resource/Init/gs_type1.ps
259 @@ -283,7 +283,7 @@ currentdict /closesourcedict .undef
261 2 copy /WeightVector exch .forceput
263 -} .bind executeonly def
264 +} .bind executeonly odef
267 % Register the font types for definefont.
268 diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps
269 index a82a2a3..7ccd4cd 100644
270 --- a/Resource/Init/pdf_base.ps
271 +++ b/Resource/Init/pdf_base.ps
272 @@ -218,7 +218,7 @@ currentdict /num-chars-dict .undef
276 -} bind executeonly def
277 +} bind executeonly odef
278 /PDFScanRules_true << /PDFScanRules //true >> def
279 /PDFScanRules_null << /PDFScanRules //null >> def
280 /.pdfrun { % <file> <opdict> .pdfrun -
281 diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
282 index d1b6ac9..c239daf 100644
283 --- a/Resource/Init/pdf_draw.ps
284 +++ b/Resource/Init/pdf_draw.ps
285 @@ -1158,7 +1158,7 @@ currentdict end readonly def
287 PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if
288 PDFfile exch setfileposition
289 -} bind executeonly def
290 +} bind executeonly odef
293 %% Get the /m from pdfopdict (must be present)
294 @@ -1189,7 +1189,7 @@ currentdict end readonly def
296 switch_to_text_marking_ops
298 -}bind executeonly def
299 +}bind executeonly odef
301 /resolvepattern { % <patternstreamdict> resolvepattern <patterndict>
302 % Don't do the resolvestream now: just capture the data
303 @@ -2353,7 +2353,7 @@ currentdict /last-ditch-bpc-csp undef
305 pdfdict /AppearanceNumber 0 .forceput
307 -}bind executeonly def
308 +}bind executeonly odef
310 /MakeAppearanceName {
311 pdfdict /AppearanceNumber get
312 @@ -2382,7 +2382,7 @@ currentdict /last-ditch-bpc-csp undef
314 pdfdict /.PreservePDFForm 3 -1 roll .forceput
316 -} bind executeonly def
317 +} bind executeonly odef
320 %% save the current value, if its true we will set it to false later, in order
321 @@ -2541,7 +2541,7 @@ currentdict /last-ditch-bpc-csp undef
324 pdfdict /.PreservePDFForm 3 -1 roll .forceput
325 -} bind executeonly def
326 +} bind executeonly odef
328 /_dops_save 1 array def
330 diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps
331 index feaf0d0..535b14a 100644
332 --- a/Resource/Init/pdf_font.ps
333 +++ b/Resource/Init/pdf_font.ps
334 @@ -718,7 +718,7 @@ currentdict end readonly def
338 -} bind executeonly def
339 +} bind executeonly odef
341 currentdict /.DoToUnicode? .forceundef
343 @@ -1241,7 +1241,7 @@ currentdict /eexec_pdf_param_dict .undef
345 dup currentdict Encoding .processToUnicode
346 currentdict end .completefont exch pop
347 -} bind executeonly def
348 +} bind executeonly odef
349 /.adjustcharwidth { % <wx> <wy> .adjustcharwidth <wx'> <wy'>
350 % Enforce the metrics, in glyph space, to the values found in the PDF Font object
351 % - force wy == 0 (assumed, and not stored in the PDF font)
352 @@ -2026,7 +2026,7 @@ currentdict /CMap_read_dict undef
354 /findresource cvx /undefined signalerror
356 -} bind executeonly def
357 +} bind executeonly odef
359 /buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font>
360 dup /BaseFont get findCIDFont exch pop
361 @@ -2211,7 +2211,7 @@ currentdict /CMap_read_dict undef
364 /MMType1 //buildType1
365 - /Type3 //buildType3
366 + /Type3 /buildType3 load
367 /TrueType //buildTrueType
368 /CIDFontType0 //buildCIDType0
369 /CIDFontType2 //buildCIDType2
370 diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps
371 index 09f8735..c823e69 100644
372 --- a/Resource/Init/pdf_main.ps
373 +++ b/Resource/Init/pdf_main.ps
374 @@ -660,7 +660,7 @@ currentdict /runpdfstring .undef
378 -} bind executeonly def
379 +} bind executeonly odef
381 currentdict /pdf_collection_files .undef
383 @@ -2715,7 +2715,7 @@ currentdict /PDF2PS_matrix_key undef
385 /RepairedAnError exch def
387 -} bind executeonly def
388 +} bind executeonly odef
390 % Display the contents of a page (including annotations).
391 /showpagecontents { % <pagedict> showpagecontents -
392 diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps
393 index c45fc51..8672d61 100644
394 --- a/Resource/Init/pdf_ops.ps
395 +++ b/Resource/Init/pdf_ops.ps
396 @@ -193,7 +193,7 @@ currentdict /gput_always_allow .undef
400 -} bind executeonly def
401 +} bind executeonly odef
404 /qstate { % - qstate <qstate>
405 @@ -451,7 +451,7 @@ currentdict /gput_always_allow .undef
406 %% a gsave, so we haven't copied it to /self, if we don't do that here
407 %% then transparent annotations cause an invalid access error.
408 currentdict //nodict eq {/self dup load end 5 dict begin def} if
409 -} bind executeonly def
410 +} bind executeonly odef
411 /AIS { .setalphaisshape } bind executeonly def
413 /.setblendmode where {
414 @@ -1077,7 +1077,7 @@ end readonly def
415 pdfopdict /v {inside_text_v} bind .forceput
416 pdfopdict /y {inside_text_y} bind .forceput
417 pdfopdict /re {inside_text_re} bind .forceput
418 -} bind executeonly def
419 +} bind executeonly odef
421 /switch_to_normal_marking_ops {
422 pdfopdict /m {normal_m} bind .forceput
423 @@ -1086,7 +1086,7 @@ end readonly def
424 pdfopdict /v {normal_v} bind .forceput
425 pdfopdict /y {normal_y} bind .forceput
426 pdfopdict /re {normal_re} bind .forceput
427 -} bind executeonly def
428 +} bind executeonly odef
431 currentdict /TextSaveMatrix known {