Brad Bishop | a34c030 | 2019-09-23 22:34:48 -0400 | [diff] [blame^] | 1 | From cd1b1cacadac2479e291efe611979bdc1b3bdb19 Mon Sep 17 00:00:00 2001 |
| 2 | From: Ken Sharp <ken.sharp@artifex.com> |
| 3 | Date: Wed, 21 Aug 2019 10:10:51 +0100 |
| 4 | Subject: [PATCH 2/2] PDF interpreter - review .forceput security |
| 5 | |
| 6 | Bug #701450 "Safer Mode Bypass by .forceput Exposure in .pdfexectoken" |
| 7 | |
| 8 | By abusing the error handler it was possible to get the PDFDEBUG portion |
| 9 | of .pdfexectoken, which uses .forceput left readable. |
| 10 | |
| 11 | Add an executeonly appropriately to make sure that clause isn't readable |
| 12 | no mstter what. |
| 13 | |
| 14 | Review all the uses of .forceput searching for similar cases, add |
| 15 | executeonly as required to secure those. All cases in the PostScript |
| 16 | support files seem to be covered already. |
| 17 | |
| 18 | CVE: CVE-2019-14817 |
| 19 | Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git] |
| 20 | |
| 21 | Signed-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 | |
| 30 | diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps |
| 31 | index 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 | } { |
| 43 | diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps |
| 44 | index 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 |
| 95 | diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps |
| 96 | index 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> |
| 174 | diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps |
| 175 | index 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 |
| 197 | diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps |
| 198 | index 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 | -- |
| 235 | 2.20.1 |
| 236 | |