From 20001d2bdf3cc60e76241a6ae72b1df01c5424c5 Mon Sep 17 00:00:00 2001 From: Chris Liddell Date: Thu, 13 Dec 2018 15:28:34 +0000 Subject: [PATCH 2/7] Any transient procedures that call .force* operators (i.e. for conditionals or loops) make them executeonly. CVE: CVE-2019-6116 Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git] Signed-off-by: Ovidiu Panait --- Resource/Init/gs_diskn.ps | 2 +- Resource/Init/gs_dps1.ps | 4 ++-- Resource/Init/gs_fntem.ps | 4 ++-- Resource/Init/gs_fonts.ps | 12 ++++++------ Resource/Init/gs_init.ps | 4 ++-- Resource/Init/gs_lev2.ps | 11 ++++++----- Resource/Init/gs_pdfwr.ps | 2 +- Resource/Init/gs_res.ps | 4 ++-- Resource/Init/gs_setpd.ps | 2 +- Resource/Init/pdf_base.ps | 13 ++++++++----- Resource/Init/pdf_draw.ps | 16 +++++++++------- Resource/Init/pdf_font.ps | 6 +++--- Resource/Init/pdf_main.ps | 4 ++-- Resource/Init/pdf_ops.ps | 7 ++++--- 14 files changed, 49 insertions(+), 42 deletions(-) diff --git a/Resource/Init/gs_diskn.ps b/Resource/Init/gs_diskn.ps index fd694bc..8bf2054 100644 --- a/Resource/Init/gs_diskn.ps +++ b/Resource/Init/gs_diskn.ps @@ -51,7 +51,7 @@ systemdict begin mark 5 1 roll ] mark exch { { } forall } forall ] //systemdict /.searchabledevs 2 index .forceput exch .setglobal - } + } executeonly if } .bind executeonly odef % must be bound and hidden for .forceput diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps index ec5db61..4fae283 100644 --- a/Resource/Init/gs_dps1.ps +++ b/Resource/Init/gs_dps1.ps @@ -78,7 +78,7 @@ level2dict begin .currentglobal { % Current mode is global; delete from local directory too. //systemdict /LocalFontDirectory .knownget - { 1 index .forceundef } % LocalFontDirectory is readonly + { 1 index .forceundef } executeonly % LocalFontDirectory is readonly if } { % Current mode is local; if there was a shadowed global @@ -126,7 +126,7 @@ level2dict begin } ifelse } forall - pop counttomark 2 idiv { .forceundef } repeat pop % readonly + pop counttomark 2 idiv { .forceundef } executeonly repeat pop % readonly } if //SharedFontDirectory exch .forcecopynew pop diff --git a/Resource/Init/gs_fntem.ps b/Resource/Init/gs_fntem.ps index c1f7651..6eb672a 100644 --- a/Resource/Init/gs_fntem.ps +++ b/Resource/Init/gs_fntem.ps @@ -401,12 +401,12 @@ currentdict end def .forceput % FontInfo can be read-only. pop % bool exit - } if + } executeonly if dup /FontInfo get % bool /GlyphNames2Unicode /Unicode /Decoding findresource .forceput % FontInfo can be read-only. exit - } loop + } executeonly loop exch setglobal } .bind executeonly odef % must be bound and hidden for .forceput diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps index 803faca..290da0c 100644 --- a/Resource/Init/gs_fonts.ps +++ b/Resource/Init/gs_fonts.ps @@ -374,7 +374,7 @@ FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if /.setnativefontmapbuilt { % set whether we've been run dup type /booleantype eq { systemdict exch /.nativefontmapbuilt exch .forceput - } + } executeonly {pop} ifelse } .bind executeonly odef @@ -1007,11 +1007,11 @@ $error /SubstituteFont { } put { 2 index gcheck currentglobal 2 copy eq { pop pop .forceput - } { + } executeonly { 5 1 roll setglobal dup length string copy .forceput setglobal - } ifelse + } executeonly ifelse } .bind executeonly odef % must be bound and hidden for .forceput % Attempt to load a font from a file. @@ -1084,7 +1084,7 @@ $error /SubstituteFont { } put .FontDirectory 3 index .forceundef % readonly 1 index (r) file .loadfont .FontDirectory exch /.setglobal .systemvar exec - } + } executeonly { .loadfont .FontDirectory } ifelse @@ -1105,7 +1105,7 @@ $error /SubstituteFont { } put dup 3 index .fontknownget { dup /PathLoad 4 index .putgstringcopy 4 1 roll pop pop pop //true exit - } if + } executeonly if % Maybe the file had a different FontName. % See if we can get a FontName from the file, and if so, @@ -1134,7 +1134,7 @@ $error /SubstituteFont { } put ifelse % Stack: origfontname fontdict exch pop //true exit % Stack: fontdict - } + } executeonly if pop % Stack: origfontname fontdirectory path } if pop pop % Stack: origfontname diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps index d733124..56c0bd2 100644 --- a/Resource/Init/gs_init.ps +++ b/Resource/Init/gs_init.ps @@ -2357,7 +2357,7 @@ SAFER { .setsafeglobal } if % Update the copy of the user parameters. mark .currentuserparams counttomark 2 idiv { userparams 3 1 roll .forceput % userparams is read-only - } repeat pop + } executeonly repeat pop % Turn on idiom recognition, if available. currentuserparams /IdiomRecognition known { /IdiomRecognition //true .definepsuserparam @@ -2376,7 +2376,7 @@ SAFER { .setsafeglobal } if % Remove real system params from pssystemparams. mark .currentsystemparams counttomark 2 idiv { pop pssystemparams exch .forceundef - } repeat pop + } executeonly repeat pop } if % Set up AlignToPixels : diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps index 44fe619..0f0d573 100644 --- a/Resource/Init/gs_lev2.ps +++ b/Resource/Init/gs_lev2.ps @@ -154,7 +154,8 @@ end % protect top level of parameters that we copied dup type dup /arraytype eq exch /stringtype eq or { readonly } if /userparams .systemvar 3 1 roll .forceput % userparams is read-only - } { + } executeonly + { pop pop } ifelse } forall @@ -224,7 +225,7 @@ end % protect top level parameters that we copied dup type dup /arraytype eq exch /stringtype eq or { readonly } if //pssystemparams 3 1 roll .forceput % pssystemparams is read-only - } + } executeonly { pop pop } ifelse @@ -934,7 +935,7 @@ mark dup /PaintProc get 1 index /Implementation known not { 1 index dup /Implementation //null .forceput readonly pop - } if + } executeonly if exec }.bind odef @@ -958,7 +959,7 @@ mark dup /PaintProc get 1 index /Implementation known not { 1 index dup /Implementation //null .forceput readonly pop - } if + } executeonly if /UNROLLFORMS where {/UNROLLFORMS get}{false}ifelse not %% [CTM] <
> PaintProc .beginform - { @@ -1005,7 +1006,7 @@ mark %% Form dictioanry using the /Implementation key). 1 dict dup /FormID 4 -1 roll put 1 index exch /Implementation exch .forceput readonly pop - } + } executeonly ifelse } { diff --git a/Resource/Init/gs_pdfwr.ps b/Resource/Init/gs_pdfwr.ps index 58e75d3..b425103 100644 --- a/Resource/Init/gs_pdfwr.ps +++ b/Resource/Init/gs_pdfwr.ps @@ -650,7 +650,7 @@ currentdict /.pdfmarkparams .undef } ifelse } bind .makeoperator .forceput systemdict /.pdf_hooked_DSC_Creator //true .forceput - } if + } executeonly if pop } if } { diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps index 8eb8bb0..d9b3459 100644 --- a/Resource/Init/gs_res.ps +++ b/Resource/Init/gs_res.ps @@ -152,7 +152,7 @@ setglobal % use .forceput / .forcedef later to replace the dummy, % empty .Instances dictionary with the real one later. readonly - } { + }{ /defineresource cvx /typecheck signaloperror } ifelse } bind executeonly odef @@ -424,7 +424,7 @@ status { % As noted above, Category dictionaries are read-only, % so we have to use .forcedef here. /.Instances 1 index .forcedef % Category dict is read-only - } if + } executeonly if } { .LocalInstances dup //.emptydict eq { pop 3 dict localinstancedict Category 2 index put diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps index e22597e..7875d1f 100644 --- a/Resource/Init/gs_setpd.ps +++ b/Resource/Init/gs_setpd.ps @@ -634,7 +634,7 @@ NOMEDIAATTRS { SETPDDEBUG { (Rolling back.) = pstack flush } if 3 index 2 index 3 -1 roll .forceput 4 index 1 index .knownget - { 4 index 3 1 roll .forceput } + { 4 index 3 1 roll .forceput } executeonly { 3 index exch .undef } ifelse } bind executeonly odef diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps index b45e980..7312729 100644 --- a/Resource/Init/pdf_base.ps +++ b/Resource/Init/pdf_base.ps @@ -130,26 +130,29 @@ currentdict /num-chars-dict .undef /.pdfexectoken { % .pdfexectoken ? PDFDEBUG { - pdfdict /PDFSTEPcount known not { pdfdict /PDFSTEPcount 1 .forceput } if + pdfdict /PDFSTEPcount known not { pdfdict /PDFSTEPcount 1 .forceput } executeonly if PDFSTEP { pdfdict /PDFtokencount 2 copy .knownget { 1 add } { 1 } ifelse .forceput PDFSTEPcount 1 gt { pdfdict /PDFSTEPcount PDFSTEPcount 1 sub .forceput - } { + } executeonly + { dup ==only ( step # ) print PDFtokencount =only ( ? ) print flush 1 //false .outputpage (%stdin) (r) file 255 string readline { token { exch pop pdfdict /PDFSTEPcount 3 -1 roll .forceput - } { + } executeonly + { pdfdict /PDFSTEPcount 1 .forceput - } ifelse % token + } executeonly ifelse % token } { pop /PDFSTEP //false def % EOF on stdin } ifelse % readline } ifelse % PDFSTEPcount > 1 - } { + } executeonly + { dup ==only () = flush } ifelse % PDFSTEP } if % PDFDEBUG diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps index 6b0ba93..40c6ac8 100644 --- a/Resource/Init/pdf_draw.ps +++ b/Resource/Init/pdf_draw.ps @@ -1118,14 +1118,14 @@ currentdict end readonly def pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror - } ifelse + } executeonly ifelse } { currentglobal pdfdict gcheck .setglobal pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror - } ifelse + } executeonly ifelse end } ifelse } loop @@ -1141,14 +1141,14 @@ currentdict end readonly def pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror - } ifelse + } executeonly ifelse } { currentglobal pdfdict gcheck .setglobal pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror - } ifelse + } executeonly ifelse } if pop @@ -2350,9 +2350,10 @@ currentdict /last-ditch-bpc-csp undef /IncrementAppearanceNumber { pdfdict /AppearanceNumber .knownget { 1 add pdfdict /AppearanceNumber 3 -1 roll .forceput - }{ + } executeonly + { pdfdict /AppearanceNumber 0 .forceput - } ifelse + } executeonly ifelse }bind executeonly odef /MakeAppearanceName { @@ -2510,7 +2511,8 @@ currentdict /last-ditch-bpc-csp undef %% want to preserve it. pdfdict /.PreservePDFForm false .forceput /q cvx /execform cvx 5 -2 roll - }{ + } executeonly + { /q cvx /PDFexecform cvx 5 -2 roll } ifelse diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps index bea9ea9..4cd62b9 100644 --- a/Resource/Init/pdf_font.ps +++ b/Resource/Init/pdf_font.ps @@ -714,7 +714,7 @@ currentdict end readonly def pop pop pop currentdict /.stackdepth .forceundef currentdict /.dstackdepth .forceundef - } + } executeonly {pop pop pop} ifelse @@ -1232,7 +1232,7 @@ currentdict /eexec_pdf_param_dict .undef (\n **** Warning: Type 3 glyph has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) pdfformatwarning pdfdict /.Qqwarning_issued //true .forceput - } if + } executeonly if Q } repeat Q @@ -2016,7 +2016,7 @@ currentdict /CMap_read_dict undef /CIDFallBack /CIDFont findresource } if exit - } if + } executeonly if } if } if diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps index 00da47a..37e69b3 100644 --- a/Resource/Init/pdf_main.ps +++ b/Resource/Init/pdf_main.ps @@ -2701,14 +2701,14 @@ currentdict /PDF2PS_matrix_key undef pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror - } ifelse + } executeonly ifelse } { currentglobal pdfdict gcheck .setglobal pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror - } ifelse + } executeonly ifelse } if } if pop diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps index 8672d61..aa09641 100644 --- a/Resource/Init/pdf_ops.ps +++ b/Resource/Init/pdf_ops.ps @@ -184,14 +184,14 @@ currentdict /gput_always_allow .undef pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror - } ifelse + } executeonly ifelse } { currentglobal pdfdict gcheck .setglobal pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror - } ifelse + } executeonly ifelse } if } bind executeonly odef @@ -439,7 +439,8 @@ currentdict /gput_always_allow .undef dup type /booleantype eq { .currentSMask type /dicttype eq { .currentSMask /Processed 2 index .forceput - } { + } executeonly + { .setSMask }ifelse }{ -- 2.18.1