| From 5845e667dda3c945ee793fbe6af021533cb4fbec Mon Sep 17 00:00:00 2001 |
| From: Ray Johnston <ray.johnston@artifex.com> |
| Date: Sun, 24 Feb 2019 22:01:04 -0800 |
| Subject: [PATCH] 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. |
| |
| CVE: CVE-2019-3835 |
| Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git] |
| |
| Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> |
| --- |
| 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 0d5c4f7..c5ac82a 100644 |
| --- a/Resource/Init/gs_init.ps |
| +++ b/Resource/Init/gs_init.ps |
| @@ -2470,24 +2470,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 <value> {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; |
| } |
| |
| -/* <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 */ |
| @@ -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.18.1 |
| |