diff --git a/SOURCES/ghostscript-cve-2019-3835.patch b/SOURCES/ghostscript-cve-2019-3835.patch new file mode 100644 index 0000000..640bb43 --- /dev/null +++ b/SOURCES/ghostscript-cve-2019-3835.patch @@ -0,0 +1,615 @@ +From 779664d79f0dca77dbdd66b753679bfd12dcbbad Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Mon, 26 Nov 2018 18:01:25 +0000 +Subject: [PATCH 1/4] Have gs_cet.ps run from gs_init.ps + +Previously gs_cet.ps was run on the command line, to set up the interpreter +state so our output more closely matches the example output for the QL CET +tests. + +Allow a -dCETMODE command line switch, which will cause gs_init.ps to run the +file directly. + +This works better for gpdl as it means the changes are made in the intial +interpreter state, rather than after initialisation is complete. + +This also means adding a definition of the default procedure for black +generation and under color removal (rather it being defined in-line in +.setdefaultbgucr + +Also, add a check so gs_cet.ps only runs once - if we try to run it a second +time, we'll just skip over the file, flushing through to the end. +--- + Resource/Init/gs_cet.ps | 11 ++++++++++- + Resource/Init/gs_init.ps | 13 ++++++++++++- + 2 files changed, 22 insertions(+), 2 deletions(-) + +diff --git a/Resource/Init/gs_cet.ps b/Resource/Init/gs_cet.ps +index d3e1686..75534bb 100644 +--- a/Resource/Init/gs_cet.ps ++++ b/Resource/Init/gs_cet.ps +@@ -1,6 +1,11 @@ + %!PS + % Set defaults for Ghostscript to match Adobe CPSI behaviour for CET + ++systemdict /product get (PhotoPRINT SE 5.0v2) readonly eq ++{ ++ (%END GS_CET) .skipeof ++} if ++ + % do this in the server level so it is persistent across jobs + //true 0 startjob not { + (*** Warning: CET startup is not in server default) = flush +@@ -25,7 +30,9 @@ currentglobal //true setglobal + + /UNROLLFORMS true def + +-{ } bind dup ++(%.defaultbgrucrproc) cvn { } bind def ++ ++(%.defaultbgrucrproc) cvn load dup + setblackgeneration + setundercolorremoval + 0 array cvx readonly dup dup dup setcolortransfer +@@ -109,3 +116,5 @@ userdict /.smoothness currentsmoothness put + % end of slightly nasty hack to give consistent cluster results + + //false 0 startjob pop % re-enter encapsulated mode ++ ++%END GS_CET +diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps +index a2503f1..9a1f2b2 100644 +--- a/Resource/Init/gs_init.ps ++++ b/Resource/Init/gs_init.ps +@@ -1534,10 +1534,18 @@ setpacking + % any-part-of-pixel rule. + 0.5 .setfilladjust + } bind def ++ + % Set the default screen and BG/UCR. ++% We define the proc here, rather than inline in .setdefaultbgucr ++% for the benefit of gs_cet.ps so jobs that do anything that causes ++% .setdefaultbgucr to be called will still get the redefined proc ++% in gs_cet.ps ++(%.defaultbgrucrproc) cvn { pop 0 } def ++ + /.setdefaultbgucr { + systemdict /setblackgeneration known { +- { pop 0 } dup setblackgeneration setundercolorremoval ++ (%.defaultbgrucrproc) cvn load dup ++ setblackgeneration setundercolorremoval + } if + } bind def + /.useloresscreen { % - .useloresscreen +@@ -2506,4 +2514,7 @@ WRITESYSTEMDICT { + % be 'true' in some cases. + userdict /AGM_preserve_spots //false put + ++systemdict /CETMODE .knownget ++{ { (gs_cet.ps) runlibfile } if } if ++ + % The interpreter will run the initial procedure (start). +-- +2.20.1 + + +From e8acf6d1aa1fc92f453175509bfdad6f2b12dc73 Mon Sep 17 00:00:00 2001 +From: Nancy Durgin +Date: Thu, 14 Feb 2019 10:09:00 -0800 +Subject: [PATCH 2/4] Undef /odef in gs_init.ps + +Made a new temporary utility function in gs_cet.ps (.odef) to use instead +of /odef. This makes it fine to undef odef with all the other operators in +gs_init.ps + +This punts the bigger question of what to do with .makeoperator, but it +doesn't make the situation any worse than it already was. +--- + Resource/Init/gs_cet.ps | 10 ++++++++-- + Resource/Init/gs_init.ps | 1 + + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/Resource/Init/gs_cet.ps b/Resource/Init/gs_cet.ps +index 75534bb..dbc5c4e 100644 +--- a/Resource/Init/gs_cet.ps ++++ b/Resource/Init/gs_cet.ps +@@ -1,6 +1,10 @@ + %!PS + % Set defaults for Ghostscript to match Adobe CPSI behaviour for CET + ++/.odef { % odef - ++ 1 index exch .makeoperator def ++} bind def ++ + systemdict /product get (PhotoPRINT SE 5.0v2) readonly eq + { + (%END GS_CET) .skipeof +@@ -93,8 +97,8 @@ userdict /.smoothness currentsmoothness put + } { + /setsmoothness .systemvar /typecheck signalerror + } ifelse +-} bind odef +-/currentsmoothness { userdict /.smoothness get } bind odef % for 09-55.PS, 09-57.PS . ++} bind //.odef exec ++/currentsmoothness { userdict /.smoothness get } bind //.odef exec % for 09-55.PS, 09-57.PS . + + % slightly nasty hack to give consistent cluster results + /ofnfa systemdict /filenameforall get def +@@ -113,6 +117,8 @@ userdict /.smoothness currentsmoothness put + } ifelse + ofnfa + } bind def ++ ++currentdict /.odef undef + % end of slightly nasty hack to give consistent cluster results + + //false 0 startjob pop % re-enter encapsulated mode +diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps +index 9a1f2b2..e5678b9 100644 +--- a/Resource/Init/gs_init.ps ++++ b/Resource/Init/gs_init.ps +@@ -2253,6 +2253,7 @@ SAFER { .setsafeglobal } if + /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams + /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice + /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack /.applypolicies ++ /odef + + % Used by a free user in the Library of Congress. Apparently this is used to + % draw a partial page, which is then filled in by the results of a barcode +-- +2.20.1 + + +From 205591753126802da850ada6511a0ff8411aa287 Mon Sep 17 00:00:00 2001 +From: Ray Johnston +Date: Thu, 14 Feb 2019 10:20:03 -0800 +Subject: [PATCH 3/4] Fix bug 700585: Restrict superexec and remove it from + internals and gs_cet.ps + +Also while changing things, restructure the CETMODE so that it will +work with -dSAFER. The gs_cet.ps is now run when we are still at save +level 0 with systemdict writeable. Allows us to undefine .makeoperator +and .setCPSImode internal operators after CETMODE is handled. + +Change previous uses of superexec to using .forceput (with the usual +.bind executeonly to hide it). +--- + Resource/Init/gs_cet.ps | 39 ++++++++++++++------------------------- + Resource/Init/gs_dps1.ps | 2 +- + Resource/Init/gs_fonts.ps | 8 ++++---- + Resource/Init/gs_init.ps | 38 +++++++++++++++++++++++++++----------- + Resource/Init/gs_ttf.ps | 6 +++--- + Resource/Init/gs_type1.ps | 6 +++--- + 6 files changed, 52 insertions(+), 47 deletions(-) + +diff --git a/Resource/Init/gs_cet.ps b/Resource/Init/gs_cet.ps +index dbc5c4e..58da404 100644 +--- a/Resource/Init/gs_cet.ps ++++ b/Resource/Init/gs_cet.ps +@@ -1,37 +1,28 @@ +-%!PS + % Set defaults for Ghostscript to match Adobe CPSI behaviour for CET + +-/.odef { % odef - +- 1 index exch .makeoperator def +-} bind def +- ++% skip if we've already run this -- based on fake "product" + systemdict /product get (PhotoPRINT SE 5.0v2) readonly eq + { + (%END GS_CET) .skipeof + } if + +-% do this in the server level so it is persistent across jobs +-//true 0 startjob not { +- (*** Warning: CET startup is not in server default) = flush +-} if ++% Note: this must be run at save level 0 and when systemdict is writeable ++currentglobal //true setglobal ++systemdict dup dup dup ++/version (3017.102) readonly .forceput % match CPSI 3017.102 ++/product (PhotoPRINT SE 5.0v2) readonly .forceput % match CPSI 3017.102 ++/revision 0 put % match CPSI 3017.103 Tek shows revision 5 ++/serialnumber dup {233640} readonly .makeoperator .forceput % match CPSI 3017.102 Tek shows serialnumber 1401788461 ++ ++systemdict /.odef { % odef - ++ 1 index exch //.makeoperator def ++} .bind .forceput % this will be undefined at the end + + 300 .sethiresscreen % needed for language switch build since it + % processes gs_init.ps BEFORE setting the resolution + + 0 array 0 setdash % CET 09-08 wants local setdash + +-currentglobal //true setglobal +- +-{ +- systemdict dup dup dup +- /version (3017.102) readonly put % match CPSI 3017.102 +- /product (PhotoPRINT SE 5.0v2) readonly put % match CPSI 3017.102 +- /revision 0 put % match CPSI 3017.103 Tek shows revision 5 +- /serialnumber dup {233640} readonly .makeoperator put % match CPSI 3017.102 Tek shows serialnumber 1401788461 +- systemdict /deviceinfo undef % for CET 20-23-1 +-% /UNROLLFORMS true put % CET files do unreasonable things inside forms +-} 1183615869 internaldict /superexec get exec +- + /UNROLLFORMS true def + + (%.defaultbgrucrproc) cvn { } bind def +@@ -118,9 +109,7 @@ userdict /.smoothness currentsmoothness put + ofnfa + } bind def + +-currentdict /.odef undef +-% end of slightly nasty hack to give consistent cluster results +- +-//false 0 startjob pop % re-enter encapsulated mode ++systemdict /.odef .undef + ++% end of slightly nasty hack to give consistent cluster results + %END GS_CET +diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps +index b75ea14..01475ac 100644 +--- a/Resource/Init/gs_dps1.ps ++++ b/Resource/Init/gs_dps1.ps +@@ -85,7 +85,7 @@ level2dict begin + % definition, copy it into the local directory. + //systemdict /SharedFontDirectory .knownget + { 1 index .knownget +- { //.FontDirectory 2 index 3 -1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly ++ { //.FontDirectory 2 index 3 -1 roll .forceput } % readonly + if + } + if +diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps +index 01eca35..ab062e1 100644 +--- a/Resource/Init/gs_fonts.ps ++++ b/Resource/Init/gs_fonts.ps +@@ -512,11 +512,11 @@ buildfontdict 3 /.buildfont3 cvx put + % the font in LocalFontDirectory. + .currentglobal + { //systemdict /LocalFontDirectory .knownget +- { 2 index 2 index { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly ++ { 2 index 2 index .forceput } % readonly + if + } + if +- dup //.FontDirectory 4 -2 roll { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly ++ dup //.FontDirectory 4 -2 roll .forceput % readonly + % If the font originated as a resource, register it. + currentfile .currentresourcefile eq { dup .registerfont } if + readonly +@@ -1178,13 +1178,13 @@ currentdict /.putgstringcopy .forceundef + //.FontDirectory 1 index known not { + 2 dict dup /FontName 3 index put + dup /FontType 1 put +- //.FontDirectory 3 1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly ++ //.FontDirectory 3 1 roll //.forceput exec % readonly + } { + pop + } ifelse + } forall + } forall +- } ++ } executeonly % hide .forceput + FAKEFONTS { exch } if pop def % don't bind, .current/setglobal get redefined + + % Install initial fonts from Fontmap. +diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps +index e5678b9..a054222 100644 +--- a/Resource/Init/gs_init.ps ++++ b/Resource/Init/gs_init.ps +@@ -2184,9 +2184,6 @@ SAFER { .setsafeglobal } if + /.endtransparencygroup % transparency-example.ps + /.setdotlength % Bug687720.ps + /.sort /.setdebug /.mementolistnewblocks /getenv +- +- /.makeoperator /.setCPSImode % gs_cet.ps, this won't work on cluster with -dSAFER +- + /unread + ] + {systemdict exch .forceundef} forall +@@ -2266,7 +2263,6 @@ SAFER { .setsafeglobal } if + + % Used by our own test suite files + %/.fileposition %image-qa.ps +- %/.makeoperator /.setCPSImode % gs_cet.ps + + % Either our code uses these in ways which mean they can't be undefined, or they are used directly by + % test files/utilities, or engineers expressed a desire to keep them visible. +@@ -2471,6 +2467,16 @@ end + /vmreclaim where + { pop NOGC not { 2 .vmreclaim 0 vmreclaim } if + } if ++ ++% Do this before systemdict is locked (see below for additional CETMODE setup using gs_cet.ps) ++systemdict /CETMODE .knownget { ++ { ++ (gs_cet.ps) runlibfile ++ } if ++} if ++systemdict /.makeoperator .undef % must be after gs_cet.ps ++systemdict /.setCPSImode .undef % must be after gs_cet.ps ++ + DELAYBIND not { + systemdict /.bindnow .undef % We only need this for DELAYBIND + systemdict /.forcecopynew .undef % remove temptation +@@ -2479,16 +2485,29 @@ DELAYBIND not { + systemdict /.forceundef .undef % ditto + } if + +-% Move superexec to internaldict if superexec is defined. +-systemdict /superexec .knownget { +- 1183615869 internaldict /superexec 3 -1 roll put +- systemdict /superexec .undef ++% Move superexec to internaldict if superexec is defined. (Level 2 or later) ++systemdict /superexec known { ++ % restrict superexec to single known use by PScript5.dll ++ % We could do this only for SAFER mode, but internaldict and superexec are ++ % not very well documented, and we don't want them to be used. ++ 1183615869 internaldict /superexec { ++ 2 index /Private eq % first check for typical use in PScript5.dll ++ 1 index length 1 eq and % expected usage is: dict /Private {put} superexec ++ 1 index 0 get systemdict /put get eq and ++ { ++ //superexec exec % the only usage we allow ++ } { ++ /superexec load /invalidaccess signalerror ++ } ifelse ++ } bind cvx executeonly put ++ systemdict /superexec .undef % get rid of the dangerous (unrestricted) operator + } if + + %% Can't remove this one until the last minute :-) + DELAYBIND not { + systemdict /.undef .undef + } if ++ + WRITESYSTEMDICT { + SAFER { + (\n *** WARNING - you have selected SAFER, indicating you want Ghostscript\n) print +@@ -2515,7 +2534,4 @@ WRITESYSTEMDICT { + % be 'true' in some cases. + userdict /AGM_preserve_spots //false put + +-systemdict /CETMODE .knownget +-{ { (gs_cet.ps) runlibfile } if } if +- + % The interpreter will run the initial procedure (start). +diff --git a/Resource/Init/gs_ttf.ps b/Resource/Init/gs_ttf.ps +index 05943c5..996d1e2 100644 +--- a/Resource/Init/gs_ttf.ps ++++ b/Resource/Init/gs_ttf.ps +@@ -1421,7 +1421,7 @@ mark + TTFDEBUG { (\n1 setting alias: ) print dup ==only + ( to be the same as ) print 2 index //== exec } if + +- 7 index 2 index 3 -1 roll exch //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse ++ 7 index 2 index 3 -1 roll exch .forceput + } forall + pop pop pop + } +@@ -1439,7 +1439,7 @@ mark + exch pop + TTFDEBUG { (\n2 setting alias: ) print 1 index ==only + ( to use glyph index: ) print dup //== exec } if +- 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse ++ 5 index 3 1 roll .forceput + //false + } + { +@@ -1456,7 +1456,7 @@ mark + { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) gindex(integer) + TTFDEBUG { (\3 nsetting alias: ) print 1 index ==only + ( to be index: ) print dup //== exec } if +- exch pop 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse ++ exch pop 5 index 3 1 roll .forceput + } + { + pop pop +@@ -1486,7 +1486,7 @@ mark + } ifelse + ] + TTFDEBUG { (Encoding: ) print dup === flush } if +-} bind def ++} .bind executeonly odef % hides .forceput + + % to be removed 9.09...... + currentdict /postalias undef +diff --git a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps +index 2935d9c..1f38dd7 100644 +--- a/Resource/Init/gs_type1.ps ++++ b/Resource/Init/gs_type1.ps +@@ -116,7 +116,7 @@ + { % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname aglname + CFFDEBUG { (\nsetting alias: ) print dup ==only + ( to be the same as glyph: ) print 1 index //== exec } if +- 3 index exch 3 index //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse ++ 3 index exch 3 index .forceput + % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname + } + {pop} ifelse +@@ -135,7 +135,7 @@ + 3 1 roll pop pop + } if + pop +- dup /.AGLprocessed~GS //true //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse ++ dup /.AGLprocessed~GS //true .forceput + } if + + %% We need to excute the C .buildfont1 in a stopped context so that, if there +@@ -148,7 +148,7 @@ + {//.buildfont1} stopped + 4 3 roll .setglobal + {//.buildfont1 $error /errorname get signalerror} if +- } bind def ++ } .bind executeonly def % hide .forceput + + % If the diskfont feature isn't included, define a dummy .loadfontdict. + /.loadfontdict where +-- +2.20.1 + + +From d683d1e6450d74619e6277efeebfc222d9a5cb91 Mon Sep 17 00:00:00 2001 +From: Ray Johnston +Date: Sun, 24 Feb 2019 22:01:04 -0800 +Subject: [PATCH 4/4] Bug 700585: Obliterate "superexec". We don't need it, nor + do any known apps. + +We were under the impression that the Windows driver 'PScript5.dll' used +superexec, but after testing with our extensive suite of PostScript file, +and analysis of the PScript5 "Adobe CoolType ProcSet, it does not appear +that this operator is needed anymore. Get rid of superexec and all of the +references to it, since it is a potential security hole. +--- + Resource/Init/gs_init.ps | 18 ------------------ + psi/icontext.c | 1 - + psi/icstate.h | 1 - + psi/zcontrol.c | 30 ------------------------------ + psi/zdict.c | 6 ++---- + psi/zgeneric.c | 3 +-- + 6 files changed, 3 insertions(+), 56 deletions(-) + +diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps +index a054222..ca20f12 100644 +--- a/Resource/Init/gs_init.ps ++++ b/Resource/Init/gs_init.ps +@@ -2485,24 +2485,6 @@ DELAYBIND not { + systemdict /.forceundef .undef % ditto + } if + +-% Move superexec to internaldict if superexec is defined. (Level 2 or later) +-systemdict /superexec known { +- % restrict superexec to single known use by PScript5.dll +- % We could do this only for SAFER mode, but internaldict and superexec are +- % not very well documented, and we don't want them to be used. +- 1183615869 internaldict /superexec { +- 2 index /Private eq % first check for typical use in PScript5.dll +- 1 index length 1 eq and % expected usage is: dict /Private {put} superexec +- 1 index 0 get systemdict /put get eq and +- { +- //superexec exec % the only usage we allow +- } { +- /superexec load /invalidaccess signalerror +- } ifelse +- } bind cvx executeonly put +- systemdict /superexec .undef % get rid of the dangerous (unrestricted) operator +-} if +- + %% Can't remove this one until the last minute :-) + DELAYBIND not { + systemdict /.undef .undef +diff --git a/psi/icontext.c b/psi/icontext.c +index 1fbe486..7462ea3 100644 +--- a/psi/icontext.c ++++ b/psi/icontext.c +@@ -151,7 +151,6 @@ context_state_alloc(gs_context_state_t ** ppcst, + pcst->rand_state = rand_state_initial; + pcst->usertime_total = 0; + pcst->keep_usertime = false; +- pcst->in_superexec = 0; + pcst->plugin_list = 0; + make_t(&pcst->error_object, t__invalid); + { /* +diff --git a/psi/icstate.h b/psi/icstate.h +index 4c6a14d..1009d85 100644 +--- a/psi/icstate.h ++++ b/psi/icstate.h +@@ -54,7 +54,6 @@ struct gs_context_state_s { + long usertime_total; /* total accumulated usertime, */ + /* not counting current time if running */ + bool keep_usertime; /* true if context ever executed usertime */ +- int in_superexec; /* # of levels of superexec */ + /* View clipping is handled in the graphics state. */ + ref error_object; /* t__invalid or error object from operator */ + ref userparams; /* t_dictionary */ +diff --git a/psi/zcontrol.c b/psi/zcontrol.c +index 0362cf4..dc813e8 100644 +--- a/psi/zcontrol.c ++++ b/psi/zcontrol.c +@@ -158,34 +158,6 @@ zexecn(i_ctx_t *i_ctx_p) + return o_push_estack; + } + +-/* superexec - */ +-static int end_superexec(i_ctx_t *); +-static int +-zsuperexec(i_ctx_t *i_ctx_p) +-{ +- os_ptr op = osp; +- es_ptr ep; +- +- check_op(1); +- if (!r_has_attr(op, a_executable)) +- return 0; /* literal object just gets pushed back */ +- check_estack(2); +- ep = esp += 3; +- make_mark_estack(ep - 2, es_other, end_superexec); /* error case */ +- make_op_estack(ep - 1, end_superexec); /* normal case */ +- ref_assign(ep, op); +- esfile_check_cache(); +- pop(1); +- i_ctx_p->in_superexec++; +- return o_push_estack; +-} +-static int +-end_superexec(i_ctx_t *i_ctx_p) +-{ +- i_ctx_p->in_superexec--; +- return 0; +-} +- + /* .runandhide */ + /* before executing , is been removed from */ + /* the operand stack and placed on the execstack with attributes */ +@@ -971,8 +943,6 @@ const op_def zcontrol3_op_defs[] = { + {"0%loop_continue", loop_continue}, + {"0%repeat_continue", repeat_continue}, + {"0%stopped_push", stopped_push}, +- {"1superexec", zsuperexec}, +- {"0%end_superexec", end_superexec}, + {"2.runandhide", zrunandhide}, + {"0%end_runandhide", end_runandhide}, + op_def_end(0) +diff --git a/psi/zdict.c b/psi/zdict.c +index b0deaaa..e2e525d 100644 +--- a/psi/zdict.c ++++ b/psi/zdict.c +@@ -212,8 +212,7 @@ zundef(i_ctx_t *i_ctx_p) + int code; + + check_type(*op1, t_dictionary); +- if (i_ctx_p->in_superexec == 0) +- check_dict_write(*op1); ++ check_dict_write(*op1); + code = idict_undef(op1, op); + if (code < 0 && code != gs_error_undefined) /* ignore undefined error */ + return code; +@@ -504,8 +503,7 @@ zsetmaxlength(i_ctx_t *i_ctx_p) + int code; + + check_type(*op1, t_dictionary); +- if (i_ctx_p->in_superexec == 0) +- check_dict_write(*op1); ++ check_dict_write(*op1); + check_type(*op, t_integer); + if (op->value.intval < 0) + return_error(gs_error_rangecheck); +diff --git a/psi/zgeneric.c b/psi/zgeneric.c +index 8048e28..d4edddb 100644 +--- a/psi/zgeneric.c ++++ b/psi/zgeneric.c +@@ -204,8 +204,7 @@ zput(i_ctx_t *i_ctx_p) + + switch (r_type(op2)) { + case t_dictionary: +- if (i_ctx_p->in_superexec == 0) +- check_dict_write(*op2); ++ check_dict_write(*op2); + { + int code = idict_put(op2, op1, op); + +-- +2.20.1 + diff --git a/SOURCES/ghostscript-cve-2019-3838.patch b/SOURCES/ghostscript-cve-2019-3838.patch new file mode 100644 index 0000000..0ba1e87 --- /dev/null +++ b/SOURCES/ghostscript-cve-2019-3838.patch @@ -0,0 +1,56 @@ +From ed9fcd95bb01f0768bf273b2526732e381202319 Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Wed, 20 Feb 2019 09:54:28 +0000 +Subject: [PATCH 1/2] Bug 700576: Make a transient proc executeonly (in + DefineResource). + +This prevents access to .forceput + +Solution originally suggested by cbuissar@redhat.com. +--- + Resource/Init/gs_res.ps | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps +index d9b3459..b646329 100644 +--- a/Resource/Init/gs_res.ps ++++ b/Resource/Init/gs_res.ps +@@ -425,7 +425,7 @@ status { + % so we have to use .forcedef here. + /.Instances 1 index .forcedef % Category dict is read-only + } executeonly if +- } ++ } executeonly + { .LocalInstances dup //.emptydict eq + { pop 3 dict localinstancedict Category 2 index put + } +-- +2.20.1 + + +From a82601e8f95a2f2147f3b3b9e44ec2b8f3a6be8b Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Fri, 22 Feb 2019 12:28:23 +0000 +Subject: [PATCH 2/2] Bug 700576(redux): an extra transient proc needs + executeonly'ed. + +--- + Resource/Init/gs_res.ps | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps +index b646329..8c1f29f 100644 +--- a/Resource/Init/gs_res.ps ++++ b/Resource/Init/gs_res.ps +@@ -437,7 +437,7 @@ status { + % Now make the resource value read-only. + 0 2 copy get { readonly } .internalstopped pop + dup 4 1 roll put exch pop exch pop +- } ++ } executeonly + { /defineresource cvx /typecheck signaloperror + } + ifelse +-- +2.20.1 + diff --git a/SOURCES/ghostscript-cve-2019-3839.patch b/SOURCES/ghostscript-cve-2019-3839.patch new file mode 100644 index 0000000..3c02934 --- /dev/null +++ b/SOURCES/ghostscript-cve-2019-3839.patch @@ -0,0 +1,866 @@ +From 95aa78beae9489d5c9f898fe2032aa23f860867d Mon Sep 17 00:00:00 2001 +From: Ray Johnston +Date: Fri, 21 Sep 2018 11:16:18 -0700 +Subject: [PATCH 1/6] Catch errors in setpagesize, .setpagesize and + setpagedevice and cleanup + +Bug 699794 showed that attempt to change page size in SAFER mode when the +nulldevice was the currentdevice would leave 'false' on the stack. Run +.setdevice in stopped and clean up, and also clean up .setpagesize +--- + Resource/Init/gs_lev2.ps | 9 ++++++++- + Resource/Init/gs_setpd.ps | 9 +++++++-- + Resource/Init/gs_statd.ps | 22 ++++++++++++++++++---- + 3 files changed, 33 insertions(+), 7 deletions(-) + +diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps +index b69303d..ab0c32e 100644 +--- a/Resource/Init/gs_lev2.ps ++++ b/Resource/Init/gs_lev2.ps +@@ -616,7 +616,14 @@ currentuserparams /WaitTimeout known + .dicttomark setpagedevice + /WaitTimeout exch mark /JobTimeout 5 2 roll .dicttomark setsystemparams + } bind def +-/.setpagesize { 2 array astore /PageSize .dict1 setpagedevice } bind def ++/.setpagesize ++ { 2 copy 2 array astore /PageSize .dict1 { setpagedevice } stopped { ++ pop % the setpagedevice dict ++ /setpagesize $error /errorname get signalerror ++ } { ++ pop pop % success -- pop the arguments ++ } ifelse ++ } bind def + /setduplexmode { /Duplex .dict1 setpagedevice } bind def + /setmargins + { exch 2 array astore /Margins .dict1 setpagedevice +diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps +index 46e5810..7875d1f 100644 +--- a/Resource/Init/gs_setpd.ps ++++ b/Resource/Init/gs_setpd.ps +@@ -932,10 +932,15 @@ SETPDDEBUG { (Recovering.) = pstack flush } if + % Stack: mark ... + SETPDDEBUG { (Installing.) = pstack flush } if + +- pop ++ pop + % .setdevice clears the current page device! + .currentpagedevice pop exch +- .setdevice pop ++ { .setdevice } stopped { ++ cleartomark exch pop ++ /setpagedevice $error /errorname get ++ signalerror ++ } if ++ pop + .setpagedevice + + % Implement UseCIEColor directly if this is a LL3 system. +diff --git a/Resource/Init/gs_statd.ps b/Resource/Init/gs_statd.ps +index 64c6463..34b759c 100644 +--- a/Resource/Init/gs_statd.ps ++++ b/Resource/Init/gs_statd.ps +@@ -39,7 +39,13 @@ statusdict begin + % These procedures are also accessed as data structures during initialization, + % so the page dimensions must be the first two elements of the procedure. + +-/.setpagesize { /statusdict .systemvar begin .setpagesize end } bind def ++/.setpagesize { ++ /statusdict .systemvar begin ++ { .setpagesize } stopped { ++ /setpagesize $error /errorname get signalerror ++ } if ++ end ++} bind def + + % Page sizes defined by Adobe documentation + % Note: these executable arrays should all begin with two +@@ -261,9 +267,17 @@ readonly def + % The Adobe documentation only defines setpagetype + % (a Level 1 operator) as accepting the values 0 and 1, + % so we do too. +- {/letter /note} 1 index get +- //systemdict /userdict get exch get cvx exec +- /pagetype exch def ++ dup type /integertype ne { ++ /setpage /typecheck signalerror ++ } { ++ dup 0 ne 1 index 1 ne or { ++ /setpage /rangecheck signalerror ++ } { ++ {/letter /note} 1 index get ++ //systemdict /userdict get exch get cvx exec ++ } ifelse ++ /pagetype exch def ++ } ifelse + end + } bind def + +-- +2.20.1 + + +From c29ec2fff76e45bbf9cd767ff541556c5d064be4 Mon Sep 17 00:00:00 2001 +From: Ray Johnston +Date: Fri, 21 Sep 2018 12:00:50 -0700 +Subject: [PATCH 2/6] Add parameter checking in setresolution + +Found in sequence for bug 699794 +--- + Resource/Init/gs_lev2.ps | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps +index ab0c32e..0f0d573 100644 +--- a/Resource/Init/gs_lev2.ps ++++ b/Resource/Init/gs_lev2.ps +@@ -637,7 +637,14 @@ currentuserparams /WaitTimeout known + .dicttomark setpagedevice + } bind def + /setresolution +- { dup 2 array astore /HWResolution .dict1 setpagedevice ++ { count 1 lt { /setresolution /stackunderflow signalerror } if ++ dup type dup /integertype eq exch /realtype eq or not ++ { ++ /setresolution /typecheck signalerror ++ } if ++ dup 2 array astore /HWResolution .dict1 { setpagedevice } stopped { ++ pop /setresolution $error /errorname get signalerror ++ } if + } bind def + %END PAGEDEVICE + +-- +2.20.1 + + +From fe4c47d8e25d6366ecbb5ff487348148b908a89e Mon Sep 17 00:00:00 2001 +From: Nancy Durgin +Date: Tue, 13 Nov 2018 14:23:41 -0800 +Subject: [PATCH 3/6] Undefine some level2-related operators + +These are only a partial set. Undefine them in both the level2dict and +systemdict. They are undef'd in gs_init.ps because they are used outside +the scope of just gs_lev2.ps + + /.execform1 + /.getdevparams + /.setuserparams2 + /.startjob + /.checkFilePermitparams + /.checksetparams + /.copyparam + /.setpagesize + +Rename .dict1 to .pair2dict and use immediate reference. + +Undef these at end of gs_lev2.ps (should never make it into systemdict): + /.pair2dict + /.checkprocesscomment +--- + Resource/Init/gs_init.ps | 18 ++++++++++++++++++ + Resource/Init/gs_lev2.ps | 34 +++++++++++++++++++++------------- + 2 files changed, 39 insertions(+), 13 deletions(-) + +diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps +index 48bb96d..e915f11 100644 +--- a/Resource/Init/gs_init.ps ++++ b/Resource/Init/gs_init.ps +@@ -2271,6 +2271,24 @@ SAFER { .setsafeglobal } if + ] + {systemdict exch .forceundef} forall + ++ % level 2 operators, undefine from both systemdict and level2dict ++ [ ++ /.execform1 ++ /.getdevparams ++ /.setuserparams2 ++ /.startjob ++ /.checkFilePermitparams ++ /.checksetparams ++ /.copyparam ++ /.setpagesize ++ ++% Couldn't figure out how to do these yet ++% /.checkparamtype ++% /.startnewjob ++ ] ++ dup {level2dict exch .forceundef} forall ++ {systemdict exch .forceundef} forall ++ + //systemdict /UndefinePostScriptOperators .forceundef + } .bind executeonly def % must be bound and hidden for .forceundef + +diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps +index 0f0d573..e6f0645 100644 +--- a/Resource/Init/gs_lev2.ps ++++ b/Resource/Init/gs_lev2.ps +@@ -64,7 +64,7 @@ level2dict begin + pop + } ifelse pop pop + } forall pop pop +-} .bind def % not odef, shouldn't reset stacks ++} .bind odef + + % currentuser/systemparams creates and returns a dictionary in the + % current VM. The easiest way to make this work is to copy any composite +@@ -101,7 +101,7 @@ level2dict begin + 1 index length string exch .setglobal + copy exch not { readonly } if + } if +-} .bind def ++} .bind odef + + % Some user parameters are managed entirely at the PostScript level. + % We take care of that here. +@@ -345,13 +345,13 @@ end + } ifelse + } .bind def + /ProcessComment //null .definepsuserparam +-psuserparams /ProcessComment {.checkprocesscomment} put ++psuserparams /ProcessComment {//.checkprocesscomment exec} put + (%ProcessComment) cvn { + /ProcessComment getuserparam + dup //null eq { pop pop pop } { exec } ifelse + } bind def + /ProcessDSCComment //null .definepsuserparam +-psuserparams /ProcessDSCComment {.checkprocesscomment} put ++psuserparams /ProcessDSCComment {//.checkprocesscomment exec} put + /.loadingfont //false def + (%ProcessDSCComment) cvn { + /ProcessDSCComment getuserparam +@@ -556,7 +556,8 @@ end % serverdict + % Note that statusdict must be allocated in local VM. + % We don't bother with many of these yet. + +-/.dict1 { exch mark 3 1 roll .dicttomark } bind def ++% convenience function to make a dictionary from an object and a key ++/.pair2dict { exch mark 3 1 roll .dicttomark } bind def + + currentglobal //false setglobal 25 dict exch setglobal begin + currentsystemparams +@@ -569,11 +570,11 @@ systemdict /buildtime dup load put + /checkpassword { .checkpassword 0 gt } bind def + dup /DoStartPage known + { /dostartpage { /DoStartPage getsystemparam } bind def +- /setdostartpage { /DoStartPage .dict1 setsystemparams } bind def ++ /setdostartpage { /DoStartPage //.pair2dict exec setsystemparams } bind def + } if + dup /StartupMode known + { /dosysstart { /StartupMode getsystemparam 0 ne } bind def +- /setdosysstart { { 1 } { 0 } ifelse /StartupMode .dict1 setsystemparams } bind def ++ /setdosysstart { { 1 } { 0 } ifelse /StartupMode //.pair2dict exec setsystemparams } bind def + } if + %****** Setting jobname is supposed to set userparams.JobName, too. + /jobname { /JobName getuserparam } bind def +@@ -581,7 +582,7 @@ dup /StartupMode known + /ramsize { /RamSize getsystemparam } bind def + /realformat 1 index /RealFormat get def + dup /PrinterName known +- { /setprintername { /PrinterName .dict1 setsystemparams } bind def ++ { /setprintername { /PrinterName //.pair2dict exec setsystemparams } bind def + } if + /printername + { currentsystemparams /PrinterName .knownget not { () } if exch copy +@@ -617,18 +618,18 @@ currentuserparams /WaitTimeout known + /WaitTimeout exch mark /JobTimeout 5 2 roll .dicttomark setsystemparams + } bind def + /.setpagesize +- { 2 copy 2 array astore /PageSize .dict1 { setpagedevice } stopped { ++ { 2 copy 2 array astore /PageSize //.pair2dict exec { setpagedevice } stopped { + pop % the setpagedevice dict + /setpagesize $error /errorname get signalerror + } { + pop pop % success -- pop the arguments + } ifelse + } bind def +-/setduplexmode { /Duplex .dict1 setpagedevice } bind def ++/setduplexmode { /Duplex //.pair2dict exec setpagedevice } bind def + /setmargins +- { exch 2 array astore /Margins .dict1 setpagedevice ++ { exch 2 array astore /Margins //.pair2dict exec setpagedevice + } bind def +-/setpagemargin { 0 2 array astore /PageOffset .dict1 setpagedevice } bind def ++/setpagemargin { 0 2 array astore /PageOffset //.pair2dict exec setpagedevice } bind def + /setpageparams + { mark /PageSize 6 -2 roll + 4 index 1 and ORIENT1 { 1 } { 0 } ifelse ne { exch } if 2 array astore +@@ -642,7 +643,7 @@ currentuserparams /WaitTimeout known + { + /setresolution /typecheck signalerror + } if +- dup 2 array astore /HWResolution .dict1 { setpagedevice } stopped { ++ dup 2 array astore /HWResolution //.pair2dict exec { setpagedevice } stopped { + pop /setresolution $error /errorname get signalerror + } if + } bind def +@@ -1254,3 +1255,10 @@ def + %END TN 5044 psuedo-ops + + end % level2dict ++ ++% undefine things defined in this file and not referenced elsewhere ++[ ++ /.checkprocesscomment ++ /.pair2dict ++] ++{level2dict exch .forceundef} forall +-- +2.20.1 + + +From 932f4106a00e99e4ee32dcc02e57d3636f383ea1 Mon Sep 17 00:00:00 2001 +From: Nancy Durgin +Date: Wed, 28 Nov 2018 10:09:01 -0800 +Subject: [PATCH 4/6] Undef internal functions from level2dict + +--- + Resource/Init/gs_lev2.ps | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps +index e6f0645..7638f2a 100644 +--- a/Resource/Init/gs_lev2.ps ++++ b/Resource/Init/gs_lev2.ps +@@ -117,7 +117,7 @@ counttomark 2 idiv { + } repeat pop + /.definepsuserparam { % .definepsuserparam - + psuserparams 3 copy pop +- type cvlit /.checkparamtype cvx 2 packedarray cvx put ++ type cvlit //.checkparamtype /exec load 3 packedarray cvx put + userparams 3 1 roll put + } .bind def + end +@@ -211,7 +211,7 @@ end + } forall + } if + /setsystemparams //pssystemparams mark exch { +- type cvlit /.checkparamtype cvx 2 packedarray cvx ++ type cvlit //.checkparamtype /exec load 3 packedarray cvx + } forall .dicttomark .checksetparams + % Set the C-level system params. If this succeeds, we know that + % the password check succeeded. +@@ -1260,5 +1260,7 @@ end % level2dict + [ + /.checkprocesscomment + /.pair2dict ++ /.setcolorrendering1 ++ /.checkparamtype + ] + {level2dict exch .forceundef} forall +-- +2.20.1 + + +From e7ff64cf9b756278f19c87d295ee0fd95c955c05 Mon Sep 17 00:00:00 2001 +From: Nancy Durgin +Date: Wed, 23 Jan 2019 12:00:30 -0800 +Subject: [PATCH 5/6] Fixed bug caused by the way .checksetparams was undef'd + +Previously, had undef'd it by making it an operator. +Now just use an immediate reference and undef it in the gs_lev2.ps file. + +This fixes bug introduced in commit fe4c47d8e25d6366ecbb5ff487348148b908a89e. + +Undef'ing .checksetparams by making it an operator doesn't work right because +errors report .checksetparams as the offending function instead of +the operator that uses it (setsystemparams in this case). + +This caused an error in file /tests_private/ps/ps3cet/27-09.PS on page 3, +where it reports the offending function of some error-handling tests. +Reporting function should be 'setsystemparams', not '.checksetparams' on +this page. +--- + Resource/Init/gs_init.ps | 1 - + Resource/Init/gs_lev2.ps | 7 ++++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps +index e915f11..a2503f1 100644 +--- a/Resource/Init/gs_init.ps ++++ b/Resource/Init/gs_init.ps +@@ -2278,7 +2278,6 @@ SAFER { .setsafeglobal } if + /.setuserparams2 + /.startjob + /.checkFilePermitparams +- /.checksetparams + /.copyparam + /.setpagesize + +diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps +index 7638f2a..de1cc94 100644 +--- a/Resource/Init/gs_lev2.ps ++++ b/Resource/Init/gs_lev2.ps +@@ -64,7 +64,7 @@ level2dict begin + pop + } ifelse pop pop + } forall pop pop +-} .bind odef ++} .bind def + + % currentuser/systemparams creates and returns a dictionary in the + % current VM. The easiest way to make this work is to copy any composite +@@ -129,7 +129,7 @@ end + /.setuserparams2 { + % Check that we will be able to set the PostScript-level + % user parameters. +- /setuserparams /psuserparams .systemvar .checksetparams ++ /setuserparams /psuserparams .systemvar //.checksetparams exec + % Set the C-level user params. If this succeeds, we know that + % the password check succeeded. + dup .setuserparams +@@ -212,7 +212,7 @@ end + } if + /setsystemparams //pssystemparams mark exch { + type cvlit //.checkparamtype /exec load 3 packedarray cvx +- } forall .dicttomark .checksetparams ++ } forall .dicttomark //.checksetparams exec + % Set the C-level system params. If this succeeds, we know that + % the password check succeeded. + dup .setsystemparams +@@ -1262,5 +1262,6 @@ end % level2dict + /.pair2dict + /.setcolorrendering1 + /.checkparamtype ++ /.checksetparams + ] + {level2dict exch .forceundef} forall +-- +2.20.1 + + +From 4ec9ca74bed49f2a82acb4bf430eae0d8b3b75c9 Mon Sep 17 00:00:00 2001 +From: Ray Johnston +Date: Thu, 31 Jan 2019 11:31:30 -0800 +Subject: [PATCH 6/6] Hide pdfdict and GS_PDF_ProcSet (internal stuff for the + PDF interp). + +We now keep GS_PDF_ProcSet in pdfdict, and immediately bind pdfdict +where needed so we can undef it after the last PDF interp file has +run (pdf_sec.ps). +--- + Resource/Init/pdf_base.ps | 11 ++++---- + Resource/Init/pdf_draw.ps | 59 +++++++++++++++++++-------------------- + Resource/Init/pdf_font.ps | 9 +++--- + Resource/Init/pdf_main.ps | 25 +++++++++-------- + Resource/Init/pdf_ops.ps | 11 ++++---- + Resource/Init/pdf_sec.ps | 4 ++- + 6 files changed, 60 insertions(+), 59 deletions(-) + +diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps +index c62ac0e..d3c3a5f 100644 +--- a/Resource/Init/pdf_base.ps ++++ b/Resource/Init/pdf_base.ps +@@ -23,7 +23,6 @@ + + /.setlanguagelevel where { pop 2 .setlanguagelevel } if + .currentglobal //true .setglobal +-/pdfdict where { pop } { /pdfdict 100 dict def } ifelse + pdfdict begin + + % Define the name interpretation dictionary for reading values. +@@ -130,11 +129,11 @@ currentdict /num-chars-dict .undef + + /.pdfexectoken { % .pdfexectoken ? + PDFDEBUG { +- pdfdict /PDFSTEPcount known not { pdfdict /PDFSTEPcount 1 .forceput } executeonly if ++ //pdfdict /PDFSTEPcount known not { //pdfdict /PDFSTEPcount 1 .forceput } executeonly if + PDFSTEP { +- pdfdict /PDFtokencount 2 copy .knownget { 1 add } { 1 } ifelse .forceput ++ //pdfdict /PDFtokencount 2 copy .knownget { 1 add } { 1 } ifelse .forceput + PDFSTEPcount 1 gt { +- pdfdict /PDFSTEPcount PDFSTEPcount 1 sub .forceput ++ //pdfdict /PDFSTEPcount PDFSTEPcount 1 sub .forceput + } executeonly + { + dup ==only +@@ -142,10 +141,10 @@ currentdict /num-chars-dict .undef + ( ? ) print flush 1 //false .outputpage + (%stdin) (r) file 255 string readline { + token { +- exch pop pdfdict /PDFSTEPcount 3 -1 roll .forceput ++ exch pop //pdfdict /PDFSTEPcount 3 -1 roll .forceput + } executeonly + { +- pdfdict /PDFSTEPcount 1 .forceput ++ //pdfdict /PDFSTEPcount 1 .forceput + } executeonly ifelse % token + } { + pop /PDFSTEP //false def % EOF on stdin +diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps +index d743ae1..1add3f7 100644 +--- a/Resource/Init/pdf_draw.ps ++++ b/Resource/Init/pdf_draw.ps +@@ -18,8 +18,7 @@ + + /.setlanguagelevel where { pop 2 .setlanguagelevel } if + .currentglobal //true .setglobal +-/pdfdict where { pop } { /pdfdict 100 dict def } ifelse +-GS_PDF_ProcSet begin ++/GS_PDF_ProcSet load begin + pdfdict begin + + % For simplicity, we use a single interpretation dictionary for all +@@ -113,7 +112,7 @@ pdfdict begin + + /resolvefunction { % resolvefunction + .resolvefn +- PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Function: ) print dup === flush } if } if ++ PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Function: ) print dup === flush } if } if + } bind executeonly def + + /resolvefnproc { % resolvefnproc +@@ -1073,7 +1072,7 @@ currentdict end readonly def + %% finished running the PaintProc. + + /.actual_pdfpaintproc { % .pdfpaintproc - +- PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Begin PaintProc) print dup === flush } if } if ++ PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Begin PaintProc) print dup === flush } if } if + PDFfile fileposition 3 1 roll + q + 1 index /PaintType oget 1 eq { +@@ -1108,21 +1107,21 @@ currentdict end readonly def + Q + }{ + (\n **** Error: File has unbalanced q/Q operators \(too many Q's\)\n Output may be incorrect.\n) +- pdfdict /.Qqwarning_issued .knownget ++ //pdfdict /.Qqwarning_issued .knownget + { + { + pop + } + { +- currentglobal pdfdict gcheck .setglobal +- pdfdict /.Qqwarning_issued //true .forceput ++ currentglobal //pdfdict gcheck .setglobal ++ //pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } executeonly ifelse + } + { +- currentglobal pdfdict gcheck .setglobal +- pdfdict /.Qqwarning_issued //true .forceput ++ currentglobal //pdfdict gcheck .setglobal ++ //pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } executeonly ifelse +@@ -1131,21 +1130,21 @@ currentdict end readonly def + } loop + { + (\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) +- pdfdict /.Qqwarning_issued .knownget ++ //pdfdict /.Qqwarning_issued .knownget + { + { + pop + } + { +- currentglobal pdfdict gcheck .setglobal +- pdfdict /.Qqwarning_issued //true .forceput ++ currentglobal //pdfdict gcheck .setglobal ++ //pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } executeonly ifelse + } + { +- currentglobal pdfdict gcheck .setglobal +- pdfdict /.Qqwarning_issued //true .forceput ++ currentglobal //pdfdict gcheck .setglobal ++ //pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } executeonly ifelse +@@ -1156,7 +1155,7 @@ currentdict end readonly def + /pdfemptycount exch def + + Q +- PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if ++ PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if + PDFfile exch setfileposition + } bind executeonly odef + +@@ -1227,7 +1226,7 @@ currentdict end readonly def + ] cvx put + dup /BBox 2 copy knownoget { normrect FixPatternBBox put } { pop pop } ifelse + dup /.pattern_uses_transparency 1 index patternusestransparency put +- PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Pattern: ) print dup === flush } if } if ++ PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Pattern: ) print dup === flush } if } if + } bind executeonly def + + /ignore_color_op ( **** Error: Ignoring a color operation in a cached context.\n Output may be incorrect.\n) readonly def +@@ -2348,16 +2347,16 @@ currentdict /last-ditch-bpc-csp undef + } bind executeonly def + + /IncrementAppearanceNumber { +- pdfdict /AppearanceNumber .knownget { +- 1 add pdfdict /AppearanceNumber 3 -1 roll .forceput ++ //pdfdict /AppearanceNumber .knownget { ++ 1 add //pdfdict /AppearanceNumber 3 -1 roll .forceput + } executeonly + { +- pdfdict /AppearanceNumber 0 .forceput ++ //pdfdict /AppearanceNumber 0 .forceput + } executeonly ifelse + }bind executeonly odef + + /MakeAppearanceName { +- pdfdict /AppearanceNumber get ++ //pdfdict /AppearanceNumber get + 10 string cvs + dup length 10 add string dup 0 (\{FormName) putinterval + dup 3 -1 roll +@@ -2378,17 +2377,17 @@ currentdict /last-ditch-bpc-csp undef + gsave initclip + MakeNewAppearanceName + .pdfFormName +- pdfdict /.PreservePDFForm known {pdfdict /.PreservePDFForm get} {//false}ifelse exch +- pdfdict /.PreservePDFForm true .forceput ++ //pdfdict /.PreservePDFForm known {//pdfdict /.PreservePDFForm get} {//false}ifelse exch ++ //pdfdict /.PreservePDFForm true .forceput + DoForm +- pdfdict /.PreservePDFForm 3 -1 roll .forceput ++ //pdfdict /.PreservePDFForm 3 -1 roll .forceput + grestore + } bind executeonly odef + + /DoForm { + %% save the current value, if its true we will set it to false later, in order + %% to prevent us preserving Forms which are used *from* an annotation /Appearance. +- pdfdict /.PreservePDFForm known {pdfdict /.PreservePDFForm get} {//false}ifelse exch ++ //pdfdict /.PreservePDFForm known {//pdfdict /.PreservePDFForm get} {//false}ifelse exch + + %% We may alter the Default* colour spaces, if the Resources + %% ColorSpace entry contains one of them. But we don't want that +@@ -2503,13 +2502,13 @@ currentdict /last-ditch-bpc-csp undef + pdfemptycount countdictstack 3 -1 roll + /pdfemptycount count 4 sub store + +- pdfdict /.PreservePDFForm known {pdfdict /.PreservePDFForm get}{//false} ifelse ++ //pdfdict /.PreservePDFForm known {//pdfdict /.PreservePDFForm get}{//false} ifelse + { + %% We must *not* preserve any subsidiary forms (curently at least) as PDF + %% form preservation doesn't really work. This is used just for Annotation + %% Appearances currently, and if they should happen to use a form, we do not + %% want to preserve it. +- pdfdict /.PreservePDFForm false .forceput ++ //pdfdict /.PreservePDFForm false .forceput + /q cvx /execform cvx 5 -2 roll + } executeonly + { +@@ -2542,7 +2541,7 @@ currentdict /last-ditch-bpc-csp undef + saved_DCMYK /DefaultCMYK exch /ColorSpace defineresource pop + end + } if +- pdfdict /.PreservePDFForm 3 -1 roll .forceput ++ //pdfdict /.PreservePDFForm 3 -1 roll .forceput + } bind executeonly odef + + /_dops_save 1 array def +@@ -2701,13 +2700,13 @@ drawopdict begin + % Start by getting the object number for a Form XObject + dup Page /XObject obj_get dup 0 eq not { + % Now get the recording dictionary and see if that object number has been seen +- pdfdict /Recursive_XObject_D get 1 index known { ++ //pdfdict /Recursive_XObject_D get 1 index known { + ( **** Error: Recursive XObject detected, ignoring ") print 1 index 256 string cvs print (", object number ) print 256 string cvs print (\n) print + ( Output may be incorrect.\n) pdfformaterror + //false + }{ + % We haven't seen it yet, so record it. +- pdfdict /Recursive_XObject_D get 1 index null put ++ //pdfdict /Recursive_XObject_D get 1 index null put + 3 1 roll + //true + }ifelse +@@ -2745,7 +2744,7 @@ drawopdict begin + ( Output may be incorrect.\n) pdfformaterror + } ifelse + PDFfile exch setfileposition +- pdfdict /Recursive_XObject_D get exch undef ++ //pdfdict /Recursive_XObject_D get exch undef + }{ + % Otherwise ignore it and tidy up the stacks + pop pop +diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps +index 46408f9..275b659 100644 +--- a/Resource/Init/pdf_font.ps ++++ b/Resource/Init/pdf_font.ps +@@ -37,8 +37,7 @@ + + /.setlanguagelevel where { pop 2 .setlanguagelevel } if + .currentglobal //true .setglobal +-/pdfdict where { pop } { /pdfdict 100 dict def } ifelse +-GS_PDF_ProcSet begin ++/GS_PDF_ProcSet load begin % from userdict at this point + pdfdict begin + + % We cache the PostScript font in an additional element of the +@@ -1219,11 +1218,11 @@ currentdict /eexec_pdf_param_dict .undef + .pdfruncontext + countdictstack BuildCharDictDepth sub + { +- pdfdict /.Qqwarning_issued .knownget {not}{//true} ifelse ++ //pdfdict /.Qqwarning_issued .knownget {not}{//true} ifelse + { + (\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 ++ //pdfdict /.Qqwarning_issued //true .forceput + } executeonly if + Q + } repeat +@@ -2334,7 +2333,7 @@ currentdict /bndef undef + dup //null eq + {pop} + { +- pdfdict /InputPDFFileName .knownget {.CRCHashFilenameAndObject} if ++ //pdfdict /InputPDFFileName .knownget {.CRCHashFilenameAndObject} if + exch dup /.OrigUniqueIDXUID .knownget not + { + dup /XUID .knownget not +diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps +index dd1480b..e44288e 100644 +--- a/Resource/Init/pdf_main.ps ++++ b/Resource/Init/pdf_main.ps +@@ -18,8 +18,9 @@ + + /.setlanguagelevel where { pop 2 .setlanguagelevel } if + .currentglobal //true .setglobal +-/pdfdict where { pop } { /pdfdict 100 dict def } ifelse + pdfdict begin ++/GS_PDF_ProcSet dup load def % keep in pdfdict to hide it ++userdict /GS_PDF_ProcSet undef + + % Patch in an obsolete variable used by some third-party software. + /#? //false def +@@ -304,8 +305,8 @@ currentdict /runpdfstring .undef + /Page //null def + /DSCPageCount 0 def + /PDFSave //null def +- GS_PDF_ProcSet begin +- pdfdict begin ++ //pdfdict /GS_PDF_ProcSet get begin ++ //pdfdict begin + pdfopen begin + /CumulativePageCount currentpagedevice /PageCount get def + } bind executeonly def +@@ -624,7 +625,7 @@ currentdict /runpdfstring .undef + %% copied to a temporary file) and store it in pdfdict. We will use this for + %% hashing fonts to detect if fonts with the same name are from different files. + %% +- dup currentglobal exch true setglobal .getfilename exch setglobal /InputPDFFileName exch pdfdict 3 1 roll .forceput ++ dup currentglobal exch true setglobal .getfilename exch setglobal /InputPDFFileName exch //pdfdict 3 1 roll .forceput + + //runpdfbegin exec + //pdf_collection_files exec +@@ -1390,7 +1391,7 @@ currentdict /xref-char-dict undef + } bind executeonly def + + /pdfopenfile { % pdfopenfile +- pdfdict readonly pop % can't do it any earlier than this ++ //pdfdict readonly pop % can't do it any earlier than this + 32 dict begin + /LocalResources 0 dict def + /DefaultQstate //null def % establish binding +@@ -2684,21 +2685,21 @@ currentdict /PDF2PS_matrix_key undef + StreamRunAborted not { + (\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) + +- pdfdict /.Qqwarning_issued .knownget ++ //pdfdict /.Qqwarning_issued .knownget + { + { + pop + } + { +- currentglobal pdfdict gcheck .setglobal +- pdfdict /.Qqwarning_issued //true .forceput ++ currentglobal //pdfdict gcheck .setglobal ++ //pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } executeonly ifelse + } + { +- currentglobal pdfdict gcheck .setglobal +- pdfdict /.Qqwarning_issued //true .forceput ++ currentglobal //pdfdict gcheck .setglobal ++ //pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } executeonly ifelse +@@ -2710,8 +2711,8 @@ currentdict /PDF2PS_matrix_key undef + Repaired % pass Repaired state around the restore + RepairedAnError + PDFSave restore +- currentglobal pdfdict gcheck .setglobal +- pdfdict /.Qqwarning_issued //false .forceput ++ currentglobal //pdfdict gcheck .setglobal ++ //pdfdict /.Qqwarning_issued //false .forceput + .setglobal + /RepairedAnError exch def + /Repaired exch def +diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps +index aa09641..c2e7461 100644 +--- a/Resource/Init/pdf_ops.ps ++++ b/Resource/Init/pdf_ops.ps +@@ -24,6 +24,7 @@ + systemdict /pdfmark known not + { userdict /pdfmark { cleartomark } bind executeonly put } if + ++systemdict /pdfdict where { pop } { /pdfdict 100 dict put } ifelse + userdict /GS_PDF_ProcSet 256 dict dup begin + + % ---------------- Abbreviations ---------------- % +@@ -174,21 +175,21 @@ currentdict /gput_always_allow .undef + { + (\n **** Error: File has unbalanced q/Q operators \(too many Q's\)\n Output may be incorrect.\n) + +- pdfdict /.Qqwarning_issued .knownget ++ //pdfdict /.Qqwarning_issued .knownget + { + { + pop + } + { +- currentglobal pdfdict gcheck .setglobal +- pdfdict /.Qqwarning_issued //true .forceput ++ currentglobal //pdfdict gcheck .setglobal ++ //pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } executeonly ifelse + } + { +- currentglobal pdfdict gcheck .setglobal +- pdfdict /.Qqwarning_issued //true .forceput ++ currentglobal //pdfdict gcheck .setglobal ++ //pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } executeonly ifelse +diff --git a/Resource/Init/pdf_sec.ps b/Resource/Init/pdf_sec.ps +index 143efb7..a8e3d2e 100644 +--- a/Resource/Init/pdf_sec.ps ++++ b/Resource/Init/pdf_sec.ps +@@ -39,7 +39,6 @@ + + /.setlanguagelevel where { pop 2 .setlanguagelevel } if + .currentglobal //true .setglobal +-/pdfdict where { pop } { /pdfdict 100 dict def } ifelse + pdfdict begin + + % Older ghostscript versions do not have .pdftoken, so we use 'token' instead. +@@ -748,4 +747,7 @@ currentdict /PDFScanRules_null undef + } bind executeonly def + + end % pdfdict ++ ++systemdict /pdfdict .forceundef % hide pdfdict ++ + .setglobal +-- +2.20.1 + diff --git a/SOURCES/ghostscript-cve-2019-6116-downstream.patch b/SOURCES/ghostscript-cve-2019-6116-downstream.patch new file mode 100644 index 0000000..0b5f15f --- /dev/null +++ b/SOURCES/ghostscript-cve-2019-6116-downstream.patch @@ -0,0 +1,48 @@ +diff --git a/Resource/Init/gs_dps.ps b/Resource/Init/gs_dps.ps +index 00c14d5..2a6f4f3 100644 +--- a/Resource/Init/gs_dps.ps ++++ b/Resource/Init/gs_dps.ps +@@ -117,7 +117,7 @@ + .dicttomark readonly /localdicts exch put + % localdicts is now defined in userdict. + % Copy the definitions into systemdict. +- localdicts { .forcedef } forall ++ localdicts { .forcedef } executeonly forall + % Set the user parameters. + userparams readonly .setuserparams + % Establish the initial gstate(s). +diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps +index 4807f81..01eca35 100644 +--- a/Resource/Init/gs_fonts.ps ++++ b/Resource/Init/gs_fonts.ps +@@ -1136,7 +1136,7 @@ $error /SubstituteFont { } put + % Stack: fontdict + } executeonly + if pop % Stack: origfontname fontdirectory path +- } ++ } executeonly + if pop pop % Stack: origfontname + + % The font definitely did not load correctly. +diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps +index f1d1728..46408f9 100644 +--- a/Resource/Init/pdf_font.ps ++++ b/Resource/Init/pdf_font.ps +@@ -678,7 +678,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 + } { +@@ -692,7 +692,7 @@ currentdict end readonly def + currentglobal exch dup gcheck setglobal + dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput + 3 2 roll setglobal +- } if % font-res font-dict encoding|null font-info g2u ++ } executeonly if % font-res font-dict encoding|null font-info g2u + exch pop exch % font-res font-dict g2u encoding|null + userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap + .convert_ToUnicode-into-g2u % font-res font-dict diff --git a/SOURCES/ghostscript-fix-DSC-comment-parsing.patch b/SOURCES/ghostscript-fix-DSC-comment-parsing.patch new file mode 100644 index 0000000..8c14643 --- /dev/null +++ b/SOURCES/ghostscript-fix-DSC-comment-parsing.patch @@ -0,0 +1,201 @@ +From f31702b38fba21153e26c3417c838618e7cfd16f Mon Sep 17 00:00:00 2001 +From: Ken Sharp +Date: Fri, 21 Sep 2018 15:28:15 +0100 +Subject: [PATCH] pdfwrite - fix DSC comment parsing + +This may affect other DSC parsing utilities. For some reason double +comment (%%) marks are being interpreted 'sometimes' in gs_init.ps +as DSC comments. This only happens when reading the init files from disk +becuase the ROM file system strips comments. + +Passing these to pdfwrite causes it to drop later DSC comments, such +as %%Title: and %%Creator: which meant the information wasn't being +embedded in the document information dictionary. + +Fix by converting double %% to single % comments, document this in the +header of gs_init.ps. +--- + Resource/Init/gs_init.ps | 93 +++++++++++++++++++++------------------- + 1 file changed, 49 insertions(+), 44 deletions(-) + +diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps +index ca20f12..d1278ea 100644 +--- a/Resource/Init/gs_init.ps ++++ b/Resource/Init/gs_init.ps +@@ -20,6 +20,11 @@ + % %% Replace + % indicate places where the next lines should be replaced by + % the contents of , when creating a single merged init file. ++% ++% For reasons not clear to me, some cases of %% are being treated as ++% DSC comments when (and only when) the resource files are disk based ++% This can kill DSC parsing for pdfwrite at least, so avoid using ++% double % comments in this file. + + % The interpreter can call out to PostScript code. All procedures + % called in this way, and no other procedures defined in these +@@ -136,12 +141,12 @@ currentdict /PDFNOCIDFALLBACK known /PDFNOCIDFALLBACK exch def + ifelse + .bind def + +-%% This was a debugging switch removed in 9.22, no other software +-%% should have had any regard for it, and even if testing its value +-%% should have checked its existence first. However pstotext, an +-%% ancient and no longer maintained piece of softare, did check +-%% its value unconditionally. So we retain this key in the dictionary +-%% purely for backward compatibility. ++% This was a debugging switch removed in 9.22, no other software ++% should have had any regard for it, and even if testing its value ++% should have checked its existence first. However pstotext, an ++% ancient and no longer maintained piece of softare, did check ++% its value unconditionally. So we retain this key in the dictionary ++% purely for backward compatibility. + /NOBIND false def + + currentdict /BATCH known /BATCH exch def +@@ -2123,12 +2128,12 @@ currentdict /tempfilepaths undef + //SAFETY /safe //true .forceput % overrides readonly + } .bind executeonly odef + +-%% This is only used during startup. Its required so that +-%% we can detect in setpagdevice that we are in fact in startup +-%% and allocate a *global* instead of local VM. We need it to be +-%% global to satisfy Display PostScript (see start of /setpagdevice +-%% in gs_setpd.ps) +-%% ++% This is only used during startup. Its required so that ++% we can detect in setpagdevice that we are in fact in startup ++% and allocate a *global* instead of local VM. We need it to be ++% global to satisfy Display PostScript (see start of /setpagdevice ++% in gs_setpd.ps) ++% + /.locksafeglobal { + .locksafe_userparams + systemdict /getenv {pop //false} put +@@ -2157,8 +2162,8 @@ currentdict /tempfilepaths undef + .locksafe + } .bind executeonly odef + +-%% See /.locksafeglobal above. +-%% ++% See /.locksafeglobal above. ++% + /.setsafeglobal { + SAFETY /safe get not { + << +@@ -2193,22 +2198,22 @@ SAFER { .setsafeglobal } if + + /UndefinePostScriptOperators { + +- %% This list is of Display PostScript operators. We believe that Display PostScript +- %% was never fully implemented and the only known user, GNUStep, is no longer +- %% using it. So lets remove it. ++ % This list is of Display PostScript operators. We believe that Display PostScript ++ % was never fully implemented and the only known user, GNUStep, is no longer ++ % using it. So lets remove it. + [ + /condition /currentcontext /detach /.fork /join /.localfork /lock /monitor /notify + /wait /yield /.currentscreenphase /.setscreenphase /.image2 /eoviewclip /initviewclip + /viewclip /viewclippath /defineusername +- %% NeXT DPS extensions ++ % NeXT DPS extensions + /currentalpha /setalpha /.alphaimage /composite /compositerect /dissolve /sizeimagebox /.sizeimageparams + ] + {systemdict exch .forceundef} forall + +- %% This list is of operators which no longer appear to be used, and which we do not believe +- %% to have any real use. For now we will undefine the operstors so they cannot easily be used +- %% but can be easily restored (just delete the name from the list in the array). In future +- %% we may remove the operator and the code implementation entirely. ++ % This list is of operators which no longer appear to be used, and which we do not believe ++ % to have any real use. For now we will undefine the operstors so they cannot easily be used ++ % but can be easily restored (just delete the name from the list in the array). In future ++ % we may remove the operator and the code implementation entirely. + [ + /.bitadd /.charboxpath /.cond /.runandhide /.popdevicefilter + /.execfile /.filenamesplit /.file_name_parent +@@ -2217,15 +2222,15 @@ SAFER { .setsafeglobal } if + /.currentlimitclamp /.dotorientation /.setaccuratecurves /.setcurvejoin /.setdashadapt /.setdotorientation + /.setlimitclamp /.currentscreenlevels /.dashpath /.pathbbox /.identeq /.identne /.tokenexec /.forgetsave /.pantonecallback + +- %% Used by our own test suite files +- %%/.setdotlength % Bug687720.ps ++ % Used by our own test suite files ++ %/.setdotlength % Bug687720.ps + ] + {systemdict exch .forceundef} forall + +- %% This list of operators are used internally by various parts of the Ghostscript startup code. +- %% Since each operator is a potential security vulnerability, and any operator listed here +- %% is not required once the initialisation is complete and functions are bound, we undefine +- %% the ones that aren't needed at runtime. ++ % This list of operators are used internally by various parts of the Ghostscript startup code. ++ % Since each operator is a potential security vulnerability, and any operator listed here ++ % is not required once the initialisation is complete and functions are bound, we undefine ++ % the ones that aren't needed at runtime. + [ + /.callinstall /.callbeginpage /.callendpage + /.currentstackprotect /.setstackprotect /.errorexec /.finderrorobject /.installsystemnames /.bosobject /.fontbbox +@@ -2297,12 +2302,12 @@ SAFER { .setsafeglobal } if + } .bind executeonly def % must be bound and hidden for .forceundef + + /UndefinePDFOperators { +- %% This list of operators are used internally by various parts of the Ghostscript PDF interpreter. +- %% Since each operator is a potential security vulnerability, and any operator listed here +- %% is not required once the initislisation is complete and functions are bound, we undefine +- %% the ones that aren't needed at runtime. +- %% This function is only called if DELAYBIND is true. It is a copy of the code at the end of pdf_main.ps +- %% and must be maintained in parallel with it. ++ % This list of operators are used internally by various parts of the Ghostscript PDF interpreter. ++ % Since each operator is a potential security vulnerability, and any operator listed here ++ % is not required once the initislisation is complete and functions are bound, we undefine ++ % the ones that aren't needed at runtime. ++ % This function is only called if DELAYBIND is true. It is a copy of the code at the end of pdf_main.ps ++ % and must be maintained in parallel with it. + [ + /.pdfawidthshow /.pdfwidthshow /.currentblackptcomp /.setblackptcomp + /.setfillcolor /.setfillcolorspace /.setstrokecolor /.setstrokecolorspace /.currentrenderingintent /.setrenderingintent +@@ -2411,13 +2416,13 @@ $error /.nosetlocal //false put + + (END GLOBAL) VMDEBUG + +-%% .savelocalstate is part of Display PostScript (if included). Part of the function of +-%% the .savelocalstate routine is to store the 'initial saved gstate' (savedinitialgstate) +-%% in systemdict. The code in dps1.c, gstate_check_space, disallows writing or creating +-%% gstates in global VM in certain conditions. If we execute setpagedevice before we +-%% reach this point, we must ensure that we do so using /..StartupGlobal so that +-%% the dictionary is defined in global VM, because the gstate contains a pointer to the +-%% device dictionary, and if that is allocated in local VM we will fail the gstate check. ++% .savelocalstate is part of Display PostScript (if included). Part of the function of ++% the .savelocalstate routine is to store the 'initial saved gstate' (savedinitialgstate) ++% in systemdict. The code in dps1.c, gstate_check_space, disallows writing or creating ++% gstates in global VM in certain conditions. If we execute setpagedevice before we ++% reach this point, we must ensure that we do so using /..StartupGlobal so that ++% the dictionary is defined in global VM, because the gstate contains a pointer to the ++% device dictionary, and if that is allocated in local VM we will fail the gstate check. + /.savelocalstate where { + % If we might create new contexts, save away copies of all dictionaries + % referenced from systemdict that are stored in local VM, +@@ -2452,8 +2457,8 @@ currentdict /.shadingtypes .undef + currentdict /.wheredict .undef + currentdict /.renderingintentdict .undef + +-%% If we are using DELAYBIND we have to defer the undefinition +-%% until .bindnow. ++% If we are using DELAYBIND we have to defer the undefinition ++% until .bindnow. + DELAYBIND not { + SAFER { + //systemdict /SAFERUndefinePostScriptOperators get exec +@@ -2485,7 +2490,7 @@ DELAYBIND not { + systemdict /.forceundef .undef % ditto + } if + +-%% Can't remove this one until the last minute :-) ++% Can't remove this one until the last minute :-) + DELAYBIND not { + systemdict /.undef .undef + } if +-- +2.20.1 + diff --git a/SOURCES/ghostscript-pdf2dsc-regression.patch b/SOURCES/ghostscript-pdf2dsc-regression.patch new file mode 100644 index 0000000..892b24b --- /dev/null +++ b/SOURCES/ghostscript-pdf2dsc-regression.patch @@ -0,0 +1,56 @@ +From db24f253409d5d085c2760c814c3e1d3fa2dac59 Mon Sep 17 00:00:00 2001 +From: Ray Johnston +Date: Tue, 19 Mar 2019 09:25:48 -0700 +Subject: Fix lib/pdf2dsc.ps to use documented Ghostscript pdf procedures. + +We eliminated GS_PDF_ProcSet and pdfdict, but runpdfbegin, dopdfpages, +and runpdfend are still available. + +diff --git a/lib/pdf2dsc.ps b/lib/pdf2dsc.ps +index 4547849c2..d836bf320 100644 +--- a/lib/pdf2dsc.ps ++++ b/lib/pdf2dsc.ps +@@ -52,10 +52,7 @@ systemdict /.setsafe known { .setsafe } if + /DSCstring 255 string def + /MediaTypes 10 dict def + +- GS_PDF_ProcSet begin +- pdfdict begin +- PDFfile +- pdfopen begin ++ PDFfile runpdfbegin + /FirstPage where { pop } { /FirstPage 1 def } ifelse + /LastPage where { pop } { /LastPage pdfpagecount def } ifelse + +@@ -108,13 +105,12 @@ systemdict /.setsafe known { .setsafe } if + (%%BeginProlog\n) puts + (/Page null def\n/Page# 0 def\n/PDFSave null def\n) puts + (/DSCPageCount 0 def\n) puts +- (/DoPDFPage {dup /Page# exch store pdfgetpage pdfshowpage } def\n) puts +- (GS_PDF_ProcSet begin\npdfdict begin\n) puts ++ (/DoPDFPage {dup /Page# exch store dup dopdfpages } def\n) puts + (%%EndProlog\n) puts + (%%BeginSetup\n) puts + DSCfile PDFname write==only + ( \(r\) file { DELAYSAFER { .setsafe } if } stopped pop\n) puts +- ( pdfopen begin\n) puts ++ ( runpdfbegin\n) puts + ( process_trailer_attrs\n) puts + (%%EndSetup\n) puts + +@@ -239,13 +235,10 @@ systemdict /.setsafe known { .setsafe } if + DSCfile exch DSCstring cvs writestring + ( DoPDFPage\n) puts + } for +- currentdict pdfclose +- end +- end +- end ++ runpdfend + % write trailer + (%%Trailer\n) puts +-(currentdict pdfclose\nend\nend\nend\n) puts ++(runpdfend\n) puts + (%%EOF\n) puts + % close output file and exit + DSCfile closefile diff --git a/SPECS/ghostscript.spec b/SPECS/ghostscript.spec index c9d9d3d..9c1fe71 100644 --- a/SPECS/ghostscript.spec +++ b/SPECS/ghostscript.spec @@ -37,7 +37,7 @@ Name: ghostscript Summary: Interpreter for PostScript language & PDF Version: 9.25 -Release: 2%{?dist} +Release: 2%{?dist}.1 License: AGPLv3+ @@ -96,6 +96,12 @@ Patch005: ghostscript-cve-2018-19475.patch Patch006: ghostscript-cve-2018-19476.patch Patch007: ghostscript-cve-2018-19477.patch Patch008: ghostscript-cve-2019-6116.patch +Patch009: ghostscript-cve-2019-6116-downstream.patch +Patch010: ghostscript-cve-2019-3839.patch +Patch011: ghostscript-cve-2019-3835.patch +Patch012: ghostscript-cve-2019-3838.patch +Patch013: ghostscript-fix-DSC-comment-parsing.patch +Patch014: ghostscript-pdf2dsc-regression.patch # Downstream patches -- these should be always included when doing rebase: # ------------------ @@ -435,6 +441,17 @@ done # ============================================================================= %changelog +* Thu Mar 28 2019 Martin Osvald - 9.25-2.1 +- Resolves: #1692798 - CVE-2019-3839 ghostscript: missing attack vector + protections for CVE-2019-6116 +- Resolves: #1678170 - CVE-2019-3835 ghostscript: superexec operator + is available (700585) +- Resolves: #1691414 - CVE-2019-3838 ghostscript: forceput in DefineResource + is still accessible (700576) +- fix included for ghostscript: Regression: double comment chars + '%%' in gs_init.ps leading to missing metadata +- fix for pdf2dsc regression added to allow fix for CVE-2019-3839 + * Wed Jan 23 2019 Martin Osvald - 9.25-2 - Resolves: #1652937 - CVE-2018-19409 ghostscript: Improperly implemented security check in zsetdevice function in psi/zdevice.c