| From cd1b1cacadac2479e291efe611979bdc1b3bdb19 Mon Sep 17 00:00:00 2001 |
| From: Ken Sharp <ken.sharp@artifex.com> |
| Date: Wed, 21 Aug 2019 10:10:51 +0100 |
| Subject: [PATCH 2/2] PDF interpreter - review .forceput security |
| |
| Bug #701450 "Safer Mode Bypass by .forceput Exposure in .pdfexectoken" |
| |
| By abusing the error handler it was possible to get the PDFDEBUG portion |
| of .pdfexectoken, which uses .forceput left readable. |
| |
| Add an executeonly appropriately to make sure that clause isn't readable |
| no mstter what. |
| |
| Review all the uses of .forceput searching for similar cases, add |
| executeonly as required to secure those. All cases in the PostScript |
| support files seem to be covered already. |
| |
| CVE: CVE-2019-14817 |
| Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git] |
| |
| Signed-off-by: Stefan Ghinea <stefan.ghinea@windriver.com> |
| --- |
| Resource/Init/pdf_base.ps | 2 +- |
| Resource/Init/pdf_draw.ps | 14 +++++++------- |
| Resource/Init/pdf_font.ps | 29 ++++++++++++++++------------- |
| Resource/Init/pdf_main.ps | 6 +++--- |
| Resource/Init/pdf_ops.ps | 11 ++++++----- |
| 5 files changed, 33 insertions(+), 29 deletions(-) |
| |
| diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps |
| index 1a218f4..cffde5c 100644 |
| --- a/Resource/Init/pdf_base.ps |
| +++ b/Resource/Init/pdf_base.ps |
| @@ -157,7 +157,7 @@ currentdict /num-chars-dict .undef |
| { |
| dup ==only () = flush |
| } ifelse % PDFSTEP |
| - } if % PDFDEBUG |
| + } executeonly if % PDFDEBUG |
| 2 copy .knownget { |
| exch pop exch pop exch pop exec |
| } { |
| diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps |
| index e18a7c2..0a3924c 100644 |
| --- a/Resource/Init/pdf_draw.ps |
| +++ b/Resource/Init/pdf_draw.ps |
| @@ -501,8 +501,8 @@ end |
| ( Output may be incorrect.\n) pdfformaterror |
| //pdfdict /.gs_warning_issued //true .forceput |
| PDFSTOPONERROR { /gs /undefined signalerror } if |
| - } if |
| - } |
| + } executeonly if |
| + } executeonly |
| ifelse |
| } bind executeonly def |
| |
| @@ -1142,7 +1142,7 @@ currentdict end readonly def |
| .setglobal |
| pdfformaterror |
| } executeonly ifelse |
| - } |
| + } executeonly |
| { |
| currentglobal //pdfdict gcheck .setglobal |
| //pdfdict /.Qqwarning_issued //true .forceput |
| @@ -1150,8 +1150,8 @@ currentdict end readonly def |
| pdfformaterror |
| } executeonly ifelse |
| end |
| - } ifelse |
| - } loop |
| + } executeonly ifelse |
| + } executeonly loop |
| { |
| (\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) |
| //pdfdict /.Qqwarning_issued .knownget |
| @@ -1165,14 +1165,14 @@ currentdict end readonly def |
| .setglobal |
| pdfformaterror |
| } executeonly ifelse |
| - } |
| + } executeonly |
| { |
| currentglobal //pdfdict gcheck .setglobal |
| //pdfdict /.Qqwarning_issued //true .forceput |
| .setglobal |
| pdfformaterror |
| } executeonly ifelse |
| - } if |
| + } executeonly if |
| pop |
| |
| % restore pdfemptycount |
| diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps |
| index 2df3303..6a6a5fe 100644 |
| --- a/Resource/Init/pdf_font.ps |
| +++ b/Resource/Init/pdf_font.ps |
| @@ -638,7 +638,7 @@ currentdict end readonly def |
| currentglobal 2 index dup gcheck setglobal |
| /FontInfo 5 dict dup 5 1 roll .forceput |
| setglobal |
| - } if |
| + } executeonly if |
| dup /GlyphNames2Unicode .knownget not { |
| //true % No existing G2U, make one |
| } { |
| @@ -668,10 +668,12 @@ currentdict end readonly def |
| pop % font-res font-dict encoding|null font-info |
| pop % font-res font-dict encoding|null |
| //false % We built a GlyphNames2Unicode table, don't need to process further |
| - }{ |
| + } executeonly |
| + { |
| //true % name is not Identity-V or H, fail by falling through |
| }ifelse |
| - } { |
| + } executeonly |
| + { |
| //true |
| } ifelse % not a name, try as a dictionary (as specified) |
| |
| @@ -759,9 +761,9 @@ currentdict end readonly def |
| PDFDEBUG { |
| (.processToUnicode end) = |
| } if |
| - } if |
| - } if |
| - } stopped |
| + } executeonly if |
| + } executeonly if |
| + } executeonly stopped |
| { |
| .dstackdepth 1 countdictstack 1 sub |
| {pop end} for |
| @@ -1291,19 +1293,20 @@ currentdict /eexec_pdf_param_dict .undef |
| //pdfdict /.Qqwarning_issued //true .forceput |
| } executeonly if |
| Q |
| - } repeat |
| + } executeonly repeat |
| Q |
| - } PDFfile fileposition 2 .execn % Keep pdfcount valid. |
| + } executeonly PDFfile fileposition 2 .execn % Keep pdfcount valid. |
| PDFfile exch setfileposition |
| - } ifelse |
| - } { |
| + } executeonly ifelse |
| + } executeonly |
| + { |
| % PDF Type 3 fonts don't use .notdef |
| % d1 implementation adjusts the width as needed |
| 0 0 0 0 0 0 |
| pdfopdict /d1 get exec |
| } ifelse |
| end end |
| - } bdef |
| + } executeonly bdef |
| dup currentdict Encoding .processToUnicode |
| currentdict end .completefont exch pop |
| } bind executeonly odef |
| @@ -2103,9 +2106,9 @@ currentdict /CMap_read_dict undef |
| (Will continue, but content may be missing.) = flush |
| } ifelse |
| } if |
| - } if |
| + } executeonly if |
| /findresource cvx /undefined signalerror |
| - } loop |
| + } executeonly loop |
| } bind executeonly odef |
| |
| /buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font> |
| diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps |
| index 5305ea6..a59e63c 100644 |
| --- a/Resource/Init/pdf_main.ps |
| +++ b/Resource/Init/pdf_main.ps |
| @@ -2749,15 +2749,15 @@ currentdict /PDF2PS_matrix_key undef |
| .setglobal |
| pdfformaterror |
| } executeonly ifelse |
| - } |
| + } executeonly |
| { |
| currentglobal //pdfdict gcheck .setglobal |
| //pdfdict /.Qqwarning_issued //true .forceput |
| .setglobal |
| pdfformaterror |
| } executeonly ifelse |
| - } if |
| - } if |
| + } executeonly if |
| + } executeonly if |
| pop |
| count PDFexecstackcount sub { pop } repeat |
| (after exec) VMDEBUG |
| diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps |
| index 285e582..6c1f100 100644 |
| --- a/Resource/Init/pdf_ops.ps |
| +++ b/Resource/Init/pdf_ops.ps |
| @@ -186,14 +186,14 @@ currentdict /gput_always_allow .undef |
| .setglobal |
| pdfformaterror |
| } executeonly ifelse |
| - } |
| + } executeonly |
| { |
| currentglobal //pdfdict gcheck .setglobal |
| //pdfdict /.Qqwarning_issued //true .forceput |
| .setglobal |
| pdfformaterror |
| } executeonly ifelse |
| - } if |
| + } executeonly if |
| } bind executeonly odef |
| |
| % Save PDF gstate |
| @@ -440,11 +440,12 @@ currentdict /gput_always_allow .undef |
| dup type /booleantype eq { |
| .currentSMask type /dicttype eq { |
| .currentSMask /Processed 2 index .forceput |
| + } executeonly |
| + { |
| + .setSMask |
| + }ifelse |
| } executeonly |
| { |
| - .setSMask |
| - }ifelse |
| - }{ |
| .setSMask |
| }ifelse |
| |
| -- |
| 2.20.1 |
| |