blob: 5228cace24ef100ce7e6d64676cf96a074cdba92 [file] [log] [blame]
Brad Bishopd89cb5f2019-04-10 09:02:41 -04001From 5845e667dda3c945ee793fbe6af021533cb4fbec Mon Sep 17 00:00:00 2001
2From: Ray Johnston <ray.johnston@artifex.com>
3Date: Sun, 24 Feb 2019 22:01:04 -0800
4Subject: [PATCH] Bug 700585: Obliterate "superexec". We don't need it, nor
5 do any known apps.
6
7We were under the impression that the Windows driver 'PScript5.dll' used
8superexec, but after testing with our extensive suite of PostScript file,
9and analysis of the PScript5 "Adobe CoolType ProcSet, it does not appear
10that this operator is needed anymore. Get rid of superexec and all of the
11references to it, since it is a potential security hole.
12
13CVE: CVE-2019-3835
14Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git]
15
16Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
17---
18 Resource/Init/gs_init.ps | 18 ------------------
19 psi/icontext.c | 1 -
20 psi/icstate.h | 1 -
21 psi/zcontrol.c | 30 ------------------------------
22 psi/zdict.c | 6 ++----
23 psi/zgeneric.c | 3 +--
24 6 files changed, 3 insertions(+), 56 deletions(-)
25
26diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
27index 0d5c4f7..c5ac82a 100644
28--- a/Resource/Init/gs_init.ps
29+++ b/Resource/Init/gs_init.ps
30@@ -2470,24 +2470,6 @@ DELAYBIND not {
31 systemdict /.forceundef .undef % ditto
32 } if
33
34-% Move superexec to internaldict if superexec is defined. (Level 2 or later)
35-systemdict /superexec known {
36- % restrict superexec to single known use by PScript5.dll
37- % We could do this only for SAFER mode, but internaldict and superexec are
38- % not very well documented, and we don't want them to be used.
39- 1183615869 internaldict /superexec {
40- 2 index /Private eq % first check for typical use in PScript5.dll
41- 1 index length 1 eq and % expected usage is: dict /Private <value> {put} superexec
42- 1 index 0 get systemdict /put get eq and
43- {
44- //superexec exec % the only usage we allow
45- } {
46- /superexec load /invalidaccess signalerror
47- } ifelse
48- } bind cvx executeonly put
49- systemdict /superexec .undef % get rid of the dangerous (unrestricted) operator
50-} if
51-
52 % Can't remove this one until the last minute :-)
53 DELAYBIND not {
54 systemdict /.undef .undef
55diff --git a/psi/icontext.c b/psi/icontext.c
56index 1fbe486..7462ea3 100644
57--- a/psi/icontext.c
58+++ b/psi/icontext.c
59@@ -151,7 +151,6 @@ context_state_alloc(gs_context_state_t ** ppcst,
60 pcst->rand_state = rand_state_initial;
61 pcst->usertime_total = 0;
62 pcst->keep_usertime = false;
63- pcst->in_superexec = 0;
64 pcst->plugin_list = 0;
65 make_t(&pcst->error_object, t__invalid);
66 { /*
67diff --git a/psi/icstate.h b/psi/icstate.h
68index 4c6a14d..1009d85 100644
69--- a/psi/icstate.h
70+++ b/psi/icstate.h
71@@ -54,7 +54,6 @@ struct gs_context_state_s {
72 long usertime_total; /* total accumulated usertime, */
73 /* not counting current time if running */
74 bool keep_usertime; /* true if context ever executed usertime */
75- int in_superexec; /* # of levels of superexec */
76 /* View clipping is handled in the graphics state. */
77 ref error_object; /* t__invalid or error object from operator */
78 ref userparams; /* t_dictionary */
79diff --git a/psi/zcontrol.c b/psi/zcontrol.c
80index 0362cf4..dc813e8 100644
81--- a/psi/zcontrol.c
82+++ b/psi/zcontrol.c
83@@ -158,34 +158,6 @@ zexecn(i_ctx_t *i_ctx_p)
84 return o_push_estack;
85 }
86
87-/* <obj> superexec - */
88-static int end_superexec(i_ctx_t *);
89-static int
90-zsuperexec(i_ctx_t *i_ctx_p)
91-{
92- os_ptr op = osp;
93- es_ptr ep;
94-
95- check_op(1);
96- if (!r_has_attr(op, a_executable))
97- return 0; /* literal object just gets pushed back */
98- check_estack(2);
99- ep = esp += 3;
100- make_mark_estack(ep - 2, es_other, end_superexec); /* error case */
101- make_op_estack(ep - 1, end_superexec); /* normal case */
102- ref_assign(ep, op);
103- esfile_check_cache();
104- pop(1);
105- i_ctx_p->in_superexec++;
106- return o_push_estack;
107-}
108-static int
109-end_superexec(i_ctx_t *i_ctx_p)
110-{
111- i_ctx_p->in_superexec--;
112- return 0;
113-}
114-
115 /* <array> <executable> .runandhide <obj> */
116 /* before executing <executable>, <array> is been removed from */
117 /* the operand stack and placed on the execstack with attributes */
118@@ -971,8 +943,6 @@ const op_def zcontrol3_op_defs[] = {
119 {"0%loop_continue", loop_continue},
120 {"0%repeat_continue", repeat_continue},
121 {"0%stopped_push", stopped_push},
122- {"1superexec", zsuperexec},
123- {"0%end_superexec", end_superexec},
124 {"2.runandhide", zrunandhide},
125 {"0%end_runandhide", end_runandhide},
126 op_def_end(0)
127diff --git a/psi/zdict.c b/psi/zdict.c
128index b0deaaa..e2e525d 100644
129--- a/psi/zdict.c
130+++ b/psi/zdict.c
131@@ -212,8 +212,7 @@ zundef(i_ctx_t *i_ctx_p)
132 int code;
133
134 check_type(*op1, t_dictionary);
135- if (i_ctx_p->in_superexec == 0)
136- check_dict_write(*op1);
137+ check_dict_write(*op1);
138 code = idict_undef(op1, op);
139 if (code < 0 && code != gs_error_undefined) /* ignore undefined error */
140 return code;
141@@ -504,8 +503,7 @@ zsetmaxlength(i_ctx_t *i_ctx_p)
142 int code;
143
144 check_type(*op1, t_dictionary);
145- if (i_ctx_p->in_superexec == 0)
146- check_dict_write(*op1);
147+ check_dict_write(*op1);
148 check_type(*op, t_integer);
149 if (op->value.intval < 0)
150 return_error(gs_error_rangecheck);
151diff --git a/psi/zgeneric.c b/psi/zgeneric.c
152index 8048e28..d4edddb 100644
153--- a/psi/zgeneric.c
154+++ b/psi/zgeneric.c
155@@ -204,8 +204,7 @@ zput(i_ctx_t *i_ctx_p)
156
157 switch (r_type(op2)) {
158 case t_dictionary:
159- if (i_ctx_p->in_superexec == 0)
160- check_dict_write(*op2);
161+ check_dict_write(*op2);
162 {
163 int code = idict_put(op2, op1, op);
164
165--
1662.18.1
167