diff options
author | Hongxu Jia <hongxu.jia@windriver.com> | 2018-11-05 16:03:36 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2018-11-07 23:08:54 +0000 |
commit | 9e2e38d349d5ac41c140761f44b96a31171d5109 (patch) | |
tree | 616061dafe409dc8229a9a107eecf42950200146 | |
parent | e84345d6e6ce129e1bffccc29b5159cb50de5ed0 (diff) | |
download | poky-9e2e38d349d5ac41c140761f44b96a31171d5109.tar.gz |
ghostscript: fix CVE-2018-18073
Artifex Ghostscript allows attackers to bypass a sandbox protection
mechanism by leveraging exposure of system operators in the saved
execution stack in an error object.
(From OE-Core rev: 6098c19e1f179896af7013c4b5db3081549c97bc)
Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
3 files changed, 241 insertions, 0 deletions
diff --git a/meta/recipes-extended/ghostscript/files/0006-Undefine-some-additional-internal-operators.patch b/meta/recipes-extended/ghostscript/files/0006-Undefine-some-additional-internal-operators.patch new file mode 100644 index 0000000000..19cf7cc8c0 --- /dev/null +++ b/meta/recipes-extended/ghostscript/files/0006-Undefine-some-additional-internal-operators.patch | |||
@@ -0,0 +1,42 @@ | |||
1 | From 37d7c9117b70e75ebed21c6c8192251f127c0fb0 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nancy Durgin <nancy.durgin@artifex.com> | ||
3 | Date: Mon, 5 Nov 2018 15:36:27 +0800 | ||
4 | Subject: [PATCH 1/2] Undefine some additional internal operators. | ||
5 | |||
6 | .type, .writecvs, .setSMask, .currentSMask | ||
7 | |||
8 | These don't seem to be referenced anywhere outside of the initialization code, | ||
9 | which binds their usages. Passes cluster if they are removed. | ||
10 | |||
11 | CVE: CVE-2018-18073 | ||
12 | Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git] | ||
13 | |||
14 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | ||
15 | --- | ||
16 | Resource/Init/gs_init.ps | 3 ++- | ||
17 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
18 | |||
19 | diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps | ||
20 | index f952f32..7c71d18 100644 | ||
21 | --- a/Resource/Init/gs_init.ps | ||
22 | +++ b/Resource/Init/gs_init.ps | ||
23 | @@ -2230,6 +2230,7 @@ SAFER { .setsafeglobal } if | ||
24 | /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile | ||
25 | /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams | ||
26 | /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath | ||
27 | + /.type /.writecvs /.setSMask /.currentSMask | ||
28 | |||
29 | % Used by a free user in the Library of Congress. Apparently this is used to | ||
30 | % draw a partial page, which is then filled in by the results of a barcode | ||
31 | @@ -2248,7 +2249,7 @@ SAFER { .setsafeglobal } if | ||
32 | % test files/utilities, or engineers expressed a desire to keep them visible. | ||
33 | % | ||
34 | %/currentdevice /.sort /.buildfont0 /.buildfont1 /.buildfont2 /.buildfont3 /.buildfont4 /.buildfont9 /.buildfont10 /.buildfont11 | ||
35 | - %/.buildfotn32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors | ||
36 | + %/.buildfont32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors | ||
37 | %/currentdevice /.quit /.setuseciecolor /.needinput /.setoverprintmode /.special_op /.dicttomark /.knownget | ||
38 | %/.FAPIavailable /.FAPIpassfont /.FAPIrebuildfont /.FAPIBuildGlyph /.FAPIBuildChar /.FAPIBuildGlyph9 | ||
39 | %/.tempfile /.numicc_components /.set_outputintent /.max /.min /.vmreclaim /.getpath /.setglobal | ||
40 | -- | ||
41 | 2.7.4 | ||
42 | |||
diff --git a/meta/recipes-extended/ghostscript/files/0007-Bug-699927-don-t-include-operator-arrays-in-execstac.patch b/meta/recipes-extended/ghostscript/files/0007-Bug-699927-don-t-include-operator-arrays-in-execstac.patch new file mode 100644 index 0000000000..ad66fc3d6e --- /dev/null +++ b/meta/recipes-extended/ghostscript/files/0007-Bug-699927-don-t-include-operator-arrays-in-execstac.patch | |||
@@ -0,0 +1,197 @@ | |||
1 | From 430f39144244ba4fd7b720cf87031e415e0fabce Mon Sep 17 00:00:00 2001 | ||
2 | From: Chris Liddell <chris.liddell@artifex.com> | ||
3 | Date: Mon, 5 Nov 2018 15:42:52 +0800 | ||
4 | Subject: [PATCH 2/2] Bug 699927: don't include operator arrays in execstack | ||
5 | output | ||
6 | |||
7 | When we transfer the contents of the execution stack into the array, take the | ||
8 | extra step of replacing any operator arrays on the stack with the operator | ||
9 | that reference them. | ||
10 | |||
11 | This prevents the contents of Postscript defined, internal only operators (those | ||
12 | created with .makeoperator) being exposed via execstack (and thus, via error | ||
13 | handling). | ||
14 | |||
15 | This necessitates a change in the resource remapping 'resource', which contains | ||
16 | a procedure which relies on the contents of the operators arrays being present. | ||
17 | As we already had internal-only variants of countexecstack and execstack | ||
18 | (.countexecstack and .execstack) - using those, and leaving thier operation | ||
19 | including the operator arrays means the procedure continues to work correctly. | ||
20 | |||
21 | Both .countexecstack and .execstack are undefined after initialization. | ||
22 | |||
23 | Also, when we store the execstack (or part thereof) for an execstackoverflow | ||
24 | error, make the same oparray/operator substitution as above for execstack. | ||
25 | |||
26 | CVE: CVE-2018-18073 | ||
27 | Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git] | ||
28 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | ||
29 | --- | ||
30 | Resource/Init/gs_init.ps | 4 ++-- | ||
31 | Resource/Init/gs_resmp.ps | 2 +- | ||
32 | psi/int.mak | 2 +- | ||
33 | psi/interp.c | 14 +++++++++++--- | ||
34 | psi/interp.h | 2 ++ | ||
35 | psi/zcontrol.c | 13 ++++++++++--- | ||
36 | 6 files changed, 27 insertions(+), 10 deletions(-) | ||
37 | |||
38 | diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps | ||
39 | index 7c71d18..f4c1053 100644 | ||
40 | --- a/Resource/Init/gs_init.ps | ||
41 | +++ b/Resource/Init/gs_init.ps | ||
42 | @@ -2191,7 +2191,7 @@ SAFER { .setsafeglobal } if | ||
43 | %% but can be easily restored (just delete the name from the list in the array). In future | ||
44 | %% we may remove the operator and the code implementation entirely. | ||
45 | [ | ||
46 | - /.bitadd /.charboxpath /.cond /.countexecstack /.execstack /.runandhide /.popdevicefilter | ||
47 | + /.bitadd /.charboxpath /.cond /.runandhide /.popdevicefilter | ||
48 | /.execfile /.filenamesplit /.file_name_parent | ||
49 | /.setdefaultmatrix /.isprocfilter /.unread /.psstringencode | ||
50 | /.buildsampledfunction /.isencapfunction /.currentaccuratecurves /.currentcurvejoin /.currentdashadapt /.currentdotlength | ||
51 | @@ -2230,7 +2230,7 @@ SAFER { .setsafeglobal } if | ||
52 | /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile | ||
53 | /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams | ||
54 | /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath | ||
55 | - /.type /.writecvs /.setSMask /.currentSMask | ||
56 | + /.type /.writecvs /.setSMask /.currentSMask /.countexecstack /.execstack | ||
57 | |||
58 | % Used by a free user in the Library of Congress. Apparently this is used to | ||
59 | % draw a partial page, which is then filled in by the results of a barcode | ||
60 | diff --git a/Resource/Init/gs_resmp.ps b/Resource/Init/gs_resmp.ps | ||
61 | index 7cacaf8..9bb4263 100644 | ||
62 | --- a/Resource/Init/gs_resmp.ps | ||
63 | +++ b/Resource/Init/gs_resmp.ps | ||
64 | @@ -183,7 +183,7 @@ setpacking | ||
65 | % We don't check them. | ||
66 | |||
67 | currentglobal //false setglobal % <object> bGlobal | ||
68 | - countexecstack array execstack % <object> bGlobal [execstack] | ||
69 | + //false .countexecstack array //false .execstack % <object> bGlobal [execstack] | ||
70 | dup //null exch % <object> bGlobal [execstack] null [execstack] | ||
71 | length 3 sub -1 0 { % <object> bGlobal [execstack] null i | ||
72 | 2 index exch get % <object> bGlobal [execstack] null proc | ||
73 | diff --git a/psi/int.mak b/psi/int.mak | ||
74 | index 5d9b3d5..6ab5bf0 100644 | ||
75 | --- a/psi/int.mak | ||
76 | +++ b/psi/int.mak | ||
77 | @@ -323,7 +323,7 @@ $(PSOBJ)zarray.$(OBJ) : $(PSSRC)zarray.c $(OP) $(memory__h)\ | ||
78 | |||
79 | $(PSOBJ)zcontrol.$(OBJ) : $(PSSRC)zcontrol.c $(OP) $(string__h)\ | ||
80 | $(estack_h) $(files_h) $(ipacked_h) $(iutil_h) $(store_h) $(stream_h)\ | ||
81 | - $(INT_MAK) $(MAKEDIRS) | ||
82 | + $(interp_h) $(INT_MAK) $(MAKEDIRS) | ||
83 | $(PSCC) $(PSO_)zcontrol.$(OBJ) $(C_) $(PSSRC)zcontrol.c | ||
84 | |||
85 | $(PSOBJ)zdict.$(OBJ) : $(PSSRC)zdict.c $(OP)\ | ||
86 | diff --git a/psi/interp.c b/psi/interp.c | ||
87 | index b70769d..6dc0dda 100644 | ||
88 | --- a/psi/interp.c | ||
89 | +++ b/psi/interp.c | ||
90 | @@ -142,7 +142,6 @@ static int oparray_pop(i_ctx_t *); | ||
91 | static int oparray_cleanup(i_ctx_t *); | ||
92 | static int zerrorexec(i_ctx_t *); | ||
93 | static int zfinderrorobject(i_ctx_t *); | ||
94 | -static int errorexec_find(i_ctx_t *, ref *); | ||
95 | static int errorexec_pop(i_ctx_t *); | ||
96 | static int errorexec_cleanup(i_ctx_t *); | ||
97 | static int zsetstackprotect(i_ctx_t *); | ||
98 | @@ -761,7 +760,7 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr) | ||
99 | { | ||
100 | uint size = ref_stack_count(pstack) - skip; | ||
101 | uint save_space = ialloc_space(idmemory); | ||
102 | - int code; | ||
103 | + int code, i; | ||
104 | |||
105 | if (size > 65535) | ||
106 | size = 65535; | ||
107 | @@ -770,6 +769,15 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr) | ||
108 | if (code >= 0) | ||
109 | code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory, | ||
110 | "copy_stack"); | ||
111 | + /* If we are copying the exec stack, try to replace any oparrays with | ||
112 | + * with the operator than references them | ||
113 | + */ | ||
114 | + if (pstack == &e_stack) { | ||
115 | + for (i = 0; i < size; i++) { | ||
116 | + if (errorexec_find(i_ctx_p, &arr->value.refs[i]) < 0) | ||
117 | + make_null(&arr->value.refs[i]); | ||
118 | + } | ||
119 | + } | ||
120 | ialloc_set_space(idmemory, save_space); | ||
121 | return code; | ||
122 | } | ||
123 | @@ -1934,7 +1942,7 @@ zfinderrorobject(i_ctx_t *i_ctx_p) | ||
124 | * .errorexec with errobj != null, store it in *perror_object and return 1, | ||
125 | * otherwise return 0; | ||
126 | */ | ||
127 | -static int | ||
128 | +int | ||
129 | errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object) | ||
130 | { | ||
131 | long i; | ||
132 | diff --git a/psi/interp.h b/psi/interp.h | ||
133 | index e9275b9..4f551d1 100644 | ||
134 | --- a/psi/interp.h | ||
135 | +++ b/psi/interp.h | ||
136 | @@ -91,5 +91,7 @@ void gs_interp_reset(i_ctx_t *i_ctx_p); | ||
137 | /* Define the top-level interface to the interpreter. */ | ||
138 | int gs_interpret(i_ctx_t **pi_ctx_p, ref * pref, int user_errors, | ||
139 | int *pexit_code, ref * perror_object); | ||
140 | +int | ||
141 | +errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object); | ||
142 | |||
143 | #endif /* interp_INCLUDED */ | ||
144 | diff --git a/psi/zcontrol.c b/psi/zcontrol.c | ||
145 | index 36da22c..0362cf4 100644 | ||
146 | --- a/psi/zcontrol.c | ||
147 | +++ b/psi/zcontrol.c | ||
148 | @@ -24,6 +24,7 @@ | ||
149 | #include "ipacked.h" | ||
150 | #include "iutil.h" | ||
151 | #include "store.h" | ||
152 | +#include "interp.h" | ||
153 | |||
154 | /* Forward references */ | ||
155 | static int check_for_exec(const_os_ptr); | ||
156 | @@ -787,7 +788,7 @@ zexecstack2(i_ctx_t *i_ctx_p) | ||
157 | /* Continuation operator to do the actual transfer. */ | ||
158 | /* r_size(op1) was set just above. */ | ||
159 | static int | ||
160 | -do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1) | ||
161 | +do_execstack(i_ctx_t *i_ctx_p, bool include_marks, bool include_oparrays, os_ptr op1) | ||
162 | { | ||
163 | os_ptr op = osp; | ||
164 | ref *arefs = op1->value.refs; | ||
165 | @@ -829,6 +830,12 @@ do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1) | ||
166 | strlen(tname), (const byte *)tname); | ||
167 | break; | ||
168 | } | ||
169 | + case t_array: | ||
170 | + case t_shortarray: | ||
171 | + case t_mixedarray: | ||
172 | + if (!include_oparrays && errorexec_find(i_ctx_p, rq) < 0) | ||
173 | + make_null(rq); | ||
174 | + break; | ||
175 | default: | ||
176 | ; | ||
177 | } | ||
178 | @@ -841,14 +848,14 @@ execstack_continue(i_ctx_t *i_ctx_p) | ||
179 | { | ||
180 | os_ptr op = osp; | ||
181 | |||
182 | - return do_execstack(i_ctx_p, false, op); | ||
183 | + return do_execstack(i_ctx_p, false, false, op); | ||
184 | } | ||
185 | static int | ||
186 | execstack2_continue(i_ctx_t *i_ctx_p) | ||
187 | { | ||
188 | os_ptr op = osp; | ||
189 | |||
190 | - return do_execstack(i_ctx_p, op->value.boolval, op - 1); | ||
191 | + return do_execstack(i_ctx_p, op->value.boolval, true, op - 1); | ||
192 | } | ||
193 | |||
194 | /* - .needinput - */ | ||
195 | -- | ||
196 | 2.7.4 | ||
197 | |||
diff --git a/meta/recipes-extended/ghostscript/ghostscript_9.25.bb b/meta/recipes-extended/ghostscript/ghostscript_9.25.bb index 55251a55d4..28521f3c4b 100644 --- a/meta/recipes-extended/ghostscript/ghostscript_9.25.bb +++ b/meta/recipes-extended/ghostscript/ghostscript_9.25.bb | |||
@@ -30,6 +30,8 @@ SRC_URI_BASE = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/d | |||
30 | file://0003-Bug-699832-add-control-over-hiding-error-handlers.patch \ | 30 | file://0003-Bug-699832-add-control-over-hiding-error-handlers.patch \ |
31 | file://0004-For-hidden-operators-pass-a-name-object-to-error-han.patch \ | 31 | file://0004-For-hidden-operators-pass-a-name-object-to-error-han.patch \ |
32 | file://0005-Bug-699938-.loadfontloop-must-be-an-operator.patch \ | 32 | file://0005-Bug-699938-.loadfontloop-must-be-an-operator.patch \ |
33 | file://0006-Undefine-some-additional-internal-operators.patch \ | ||
34 | file://0007-Bug-699927-don-t-include-operator-arrays-in-execstac.patch \ | ||
33 | " | 35 | " |
34 | 36 | ||
35 | SRC_URI = "${SRC_URI_BASE} \ | 37 | SRC_URI = "${SRC_URI_BASE} \ |