| From: Ray Johnston <ray.johnston@artifex.com> |
| Date: Thu, 14 Feb 2019 18:20:03 +0000 (-0800) |
| Subject: Fix bug 700585: Restrict superexec and remove it from internals and gs_cet.ps |
| |
| 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). |
| |
| https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=205591753126802da850ada6511a0ff8411aa287 |
| |
| From: Ray Johnston <ray.johnston@artifex.com> |
| Date: Mon, 25 Feb 2019 06:01:04 +0000 (-0800) |
| Subject: Bug 700585: Obliterate "superexec". We don't need it, nor do any known apps. |
| |
| 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. |
| |
| https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=d683d1e6450d74619e6277efeebfc222d9a5cb91 |
| |
| |
| diff -up ghostscript-9.07/psi/icontext.c.cve-2019-3835 ghostscript-9.07/psi/icontext.c |
| |
| |
| @@ -148,7 +148,6 @@ context_state_alloc(gs_context_state_t * |
| 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 -up ghostscript-9.07/psi/icstate.h.cve-2019-3835 ghostscript-9.07/psi/icstate.h |
| |
| |
| @@ -52,7 +52,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 -up ghostscript-9.07/psi/zcontrol.c.cve-2019-3835 ghostscript-9.07/psi/zcontrol.c |
| |
| |
| @@ -158,34 +158,6 @@ zexecn(i_ctx_t *i_ctx_p) |
| return o_push_estack; |
| } |
| |
| -/* <obj> 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; |
| -} |
| - |
| /* <array> <executable> .runandhide <obj> */ |
| /* before executing <executable>, <array> is been removed from */ |
| /* the operand stack and placed on the execstack with attributes */ |
| @@ -969,8 +941,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 -up ghostscript-9.07/psi/zdict.c.cve-2019-3835 ghostscript-9.07/psi/zdict.c |
| |
| |
| @@ -211,8 +211,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 != e_undefined) /* ignore undefined error */ |
| return code; |
| @@ -491,8 +490,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(e_rangecheck); |
| diff -up ghostscript-9.07/psi/zgeneric.c.cve-2019-3835 ghostscript-9.07/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); |
| |
| diff -up ghostscript-9.07/Resource/Init/gs_cet.ps.cve-2019-3835 ghostscript-9.07/Resource/Init/gs_cet.ps |
| |
| |
| @@ -1,27 +1,22 @@ |
| -%!PS |
| % Set defaults for Ghostscript to match Adobe CPSI behaviour for CET |
| |
| -% 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 { % <name> <proc> 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 |
| -} 1183615869 internaldict /superexec get exec |
| - |
| { } bind dup |
| setblackgeneration |
| setundercolorremoval |
| @@ -69,4 +64,4 @@ userdict /.smoothness currentsmoothness |
| } bind odef |
| /currentsmoothness { userdict /.smoothness get } bind odef % for 09-55.PS, 09-57.PS . |
| |
| -//false 0 startjob pop % re-enter encapsulated mode |
| +systemdict /.odef .undef |
| diff -up ghostscript-9.07/Resource/Init/gs_dps1.ps.cve-2019-3835 ghostscript-9.07/Resource/Init/gs_dps1.ps |
| |
| |
| @@ -86,7 +86,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 -up ghostscript-9.07/Resource/Init/gs_fonts.ps.cve-2019-3835 ghostscript-9.07/Resource/Init/gs_fonts.ps |
| |
| |
| @@ -501,11 +501,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 |
| @@ -1149,12 +1149,12 @@ 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 |
| - } |
| + } executeonly % hide .forceput |
| FAKEFONTS { exch } if pop def % don't bind, .current/setglobal get redefined |
| |
| % Install initial fonts from Fontmap. |
| diff -up ghostscript-9.07/Resource/Init/gs_init.ps.cve-2019-3835 ghostscript-9.07/Resource/Init/gs_init.ps |
| |
| |
| @@ -2125,9 +2125,6 @@ SAFER { .setsafe } 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 |
| @@ -2206,7 +2203,6 @@ SAFER { .setsafe } 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. |
| @@ -2400,6 +2396,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 |
| @@ -2407,11 +2413,6 @@ DELAYBIND not { |
| systemdict /.forceput .undef % ditto |
| 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 |
| -} if |
| |
| % Can't remove this one until the last minute :-) |
| systemdict /.undef .undef |
| diff -up ghostscript-9.07/Resource/Init/gs_type1.ps.cve-2019-3835 ghostscript-9.07/Resource/Init/gs_type1.ps |
| |
| |
| @@ -66,11 +66,11 @@ |
| 2 index 1 index known { |
| pop pop |
| } { |
| - 3 1 roll get //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse dup dup |
| + 3 1 roll get .forceput dup dup |
| } ifelse |
| } { |
| 2 index 1 index known { |
| - exch 3 1 roll get //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse dup dup |
| + exch 3 1 roll get .forceput dup dup |
| } { |
| pop pop |
| } ifelse |
| @@ -80,7 +80,7 @@ |
| |
| //.buildfont1 |
| 3 2 roll .setglobal |
| - } bind def |
| + } .bind executeonly def % hide .forceput |
| |
| % If the diskfont feature isn't included, define a dummy .loadfontdict. |
| /.loadfontdict where |