blob: 6348fff2d13ae154c32412110f6778ed584a7999 [file] [log] [blame]
Brad Bishopa34c0302019-09-23 22:34:48 -04001From cd1b1cacadac2479e291efe611979bdc1b3bdb19 Mon Sep 17 00:00:00 2001
2From: Ken Sharp <ken.sharp@artifex.com>
3Date: Wed, 21 Aug 2019 10:10:51 +0100
4Subject: [PATCH 2/2] PDF interpreter - review .forceput security
5
6Bug #701450 "Safer Mode Bypass by .forceput Exposure in .pdfexectoken"
7
8By abusing the error handler it was possible to get the PDFDEBUG portion
9of .pdfexectoken, which uses .forceput left readable.
10
11Add an executeonly appropriately to make sure that clause isn't readable
12no mstter what.
13
14Review all the uses of .forceput searching for similar cases, add
15executeonly as required to secure those. All cases in the PostScript
16support files seem to be covered already.
17
18CVE: CVE-2019-14817
19Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git]
20
21Signed-off-by: Stefan Ghinea <stefan.ghinea@windriver.com>
22---
23 Resource/Init/pdf_base.ps | 2 +-
24 Resource/Init/pdf_draw.ps | 14 +++++++-------
25 Resource/Init/pdf_font.ps | 29 ++++++++++++++++-------------
26 Resource/Init/pdf_main.ps | 6 +++---
27 Resource/Init/pdf_ops.ps | 11 ++++++-----
28 5 files changed, 33 insertions(+), 29 deletions(-)
29
30diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps
31index 1a218f4..cffde5c 100644
32--- a/Resource/Init/pdf_base.ps
33+++ b/Resource/Init/pdf_base.ps
34@@ -157,7 +157,7 @@ currentdict /num-chars-dict .undef
35 {
36 dup ==only () = flush
37 } ifelse % PDFSTEP
38- } if % PDFDEBUG
39+ } executeonly if % PDFDEBUG
40 2 copy .knownget {
41 exch pop exch pop exch pop exec
42 } {
43diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
44index e18a7c2..0a3924c 100644
45--- a/Resource/Init/pdf_draw.ps
46+++ b/Resource/Init/pdf_draw.ps
47@@ -501,8 +501,8 @@ end
48 ( Output may be incorrect.\n) pdfformaterror
49 //pdfdict /.gs_warning_issued //true .forceput
50 PDFSTOPONERROR { /gs /undefined signalerror } if
51- } if
52- }
53+ } executeonly if
54+ } executeonly
55 ifelse
56 } bind executeonly def
57
58@@ -1142,7 +1142,7 @@ currentdict end readonly def
59 .setglobal
60 pdfformaterror
61 } executeonly ifelse
62- }
63+ } executeonly
64 {
65 currentglobal //pdfdict gcheck .setglobal
66 //pdfdict /.Qqwarning_issued //true .forceput
67@@ -1150,8 +1150,8 @@ currentdict end readonly def
68 pdfformaterror
69 } executeonly ifelse
70 end
71- } ifelse
72- } loop
73+ } executeonly ifelse
74+ } executeonly loop
75 {
76 (\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n)
77 //pdfdict /.Qqwarning_issued .knownget
78@@ -1165,14 +1165,14 @@ currentdict end readonly def
79 .setglobal
80 pdfformaterror
81 } executeonly ifelse
82- }
83+ } executeonly
84 {
85 currentglobal //pdfdict gcheck .setglobal
86 //pdfdict /.Qqwarning_issued //true .forceput
87 .setglobal
88 pdfformaterror
89 } executeonly ifelse
90- } if
91+ } executeonly if
92 pop
93
94 % restore pdfemptycount
95diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps
96index 2df3303..6a6a5fe 100644
97--- a/Resource/Init/pdf_font.ps
98+++ b/Resource/Init/pdf_font.ps
99@@ -638,7 +638,7 @@ currentdict end readonly def
100 currentglobal 2 index dup gcheck setglobal
101 /FontInfo 5 dict dup 5 1 roll .forceput
102 setglobal
103- } if
104+ } executeonly if
105 dup /GlyphNames2Unicode .knownget not {
106 //true % No existing G2U, make one
107 } {
108@@ -668,10 +668,12 @@ currentdict end readonly def
109 pop % font-res font-dict encoding|null font-info
110 pop % font-res font-dict encoding|null
111 //false % We built a GlyphNames2Unicode table, don't need to process further
112- }{
113+ } executeonly
114+ {
115 //true % name is not Identity-V or H, fail by falling through
116 }ifelse
117- } {
118+ } executeonly
119+ {
120 //true
121 } ifelse % not a name, try as a dictionary (as specified)
122
123@@ -759,9 +761,9 @@ currentdict end readonly def
124 PDFDEBUG {
125 (.processToUnicode end) =
126 } if
127- } if
128- } if
129- } stopped
130+ } executeonly if
131+ } executeonly if
132+ } executeonly stopped
133 {
134 .dstackdepth 1 countdictstack 1 sub
135 {pop end} for
136@@ -1291,19 +1293,20 @@ currentdict /eexec_pdf_param_dict .undef
137 //pdfdict /.Qqwarning_issued //true .forceput
138 } executeonly if
139 Q
140- } repeat
141+ } executeonly repeat
142 Q
143- } PDFfile fileposition 2 .execn % Keep pdfcount valid.
144+ } executeonly PDFfile fileposition 2 .execn % Keep pdfcount valid.
145 PDFfile exch setfileposition
146- } ifelse
147- } {
148+ } executeonly ifelse
149+ } executeonly
150+ {
151 % PDF Type 3 fonts don't use .notdef
152 % d1 implementation adjusts the width as needed
153 0 0 0 0 0 0
154 pdfopdict /d1 get exec
155 } ifelse
156 end end
157- } bdef
158+ } executeonly bdef
159 dup currentdict Encoding .processToUnicode
160 currentdict end .completefont exch pop
161 } bind executeonly odef
162@@ -2103,9 +2106,9 @@ currentdict /CMap_read_dict undef
163 (Will continue, but content may be missing.) = flush
164 } ifelse
165 } if
166- } if
167+ } executeonly if
168 /findresource cvx /undefined signalerror
169- } loop
170+ } executeonly loop
171 } bind executeonly odef
172
173 /buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font>
174diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps
175index 5305ea6..a59e63c 100644
176--- a/Resource/Init/pdf_main.ps
177+++ b/Resource/Init/pdf_main.ps
178@@ -2749,15 +2749,15 @@ currentdict /PDF2PS_matrix_key undef
179 .setglobal
180 pdfformaterror
181 } executeonly ifelse
182- }
183+ } executeonly
184 {
185 currentglobal //pdfdict gcheck .setglobal
186 //pdfdict /.Qqwarning_issued //true .forceput
187 .setglobal
188 pdfformaterror
189 } executeonly ifelse
190- } if
191- } if
192+ } executeonly if
193+ } executeonly if
194 pop
195 count PDFexecstackcount sub { pop } repeat
196 (after exec) VMDEBUG
197diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps
198index 285e582..6c1f100 100644
199--- a/Resource/Init/pdf_ops.ps
200+++ b/Resource/Init/pdf_ops.ps
201@@ -186,14 +186,14 @@ currentdict /gput_always_allow .undef
202 .setglobal
203 pdfformaterror
204 } executeonly ifelse
205- }
206+ } executeonly
207 {
208 currentglobal //pdfdict gcheck .setglobal
209 //pdfdict /.Qqwarning_issued //true .forceput
210 .setglobal
211 pdfformaterror
212 } executeonly ifelse
213- } if
214+ } executeonly if
215 } bind executeonly odef
216
217 % Save PDF gstate
218@@ -440,11 +440,12 @@ currentdict /gput_always_allow .undef
219 dup type /booleantype eq {
220 .currentSMask type /dicttype eq {
221 .currentSMask /Processed 2 index .forceput
222+ } executeonly
223+ {
224+ .setSMask
225+ }ifelse
226 } executeonly
227 {
228- .setSMask
229- }ifelse
230- }{
231 .setSMask
232 }ifelse
233
234--
2352.20.1
236