summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChee Yang Lee <chee.yang.lee@intel.com>2022-03-17 15:32:44 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-03-22 22:18:56 +0000
commit984de2b68a0e95abbad1c99e55f4fcf77088544a (patch)
tree701187d66ab4d287a9a53a426e43697dcfa6d3b8
parent630d754ea3d7206976b1e0f4489e054cdbc08fe8 (diff)
downloadpoky-984de2b68a0e95abbad1c99e55f4fcf77088544a.tar.gz
ghostscript: fix CVE-2021-3781
(From OE-Core rev: c9c5254345249b8a2c53e80cec3c469ca6fc1099) Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com> Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781.patch236
-rw-r--r--meta/recipes-extended/ghostscript/ghostscript_9.54.0.bb1
2 files changed, 237 insertions, 0 deletions
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781.patch
new file mode 100644
index 0000000000..27ef83bb85
--- /dev/null
+++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781.patch
@@ -0,0 +1,236 @@
1From a9bd3dec9fde03327a4a2c69dad1036bf9632e20 Mon Sep 17 00:00:00 2001
2From: Chris Liddell <chris.liddell@artifex.com>
3Date: Tue, 7 Sep 2021 20:36:12 +0100
4Subject: [PATCH] Bug 704342: Include device specifier strings in access
5 validation
6
7for the "%pipe%", %handle%" and %printer% io devices.
8
9We previously validated only the part after the "%pipe%" Postscript device
10specifier, but this proved insufficient.
11
12This rebuilds the original file name string, and validates it complete. The
13slight complication for "%pipe%" is it can be reached implicitly using
14"|" so we have to check both prefixes.
15
16Addresses CVE-2021-3781
17
18Upstream-Status: Backport[https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=a9bd3dec9fde03327a4a2c69dad1036bf9632e20]
19CVE: CVE-2021-3781
20Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
21---
22 base/gdevpipe.c | 22 +++++++++++++++-
23 base/gp_mshdl.c | 11 +++++++-
24 base/gp_msprn.c | 10 ++++++-
25 base/gp_os2pr.c | 13 +++++++++-
26 base/gslibctx.c | 69 ++++++++++---------------------------------------
27 5 files changed, 65 insertions(+), 60 deletions(-)
28
29diff --git a/base/gdevpipe.c b/base/gdevpipe.c
30index 96d71f5d8..5bdc485be 100644
31--- a/base/gdevpipe.c
32+++ b/base/gdevpipe.c
33@@ -72,8 +72,28 @@ pipe_fopen(gx_io_device * iodev, const char *fname, const char *access,
34 #else
35 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
36 gs_fs_list_t *fs = ctx->core->fs;
37+ /* The pipe device can be reached in two ways, explicltly with %pipe%
38+ or implicitly with "|", so we have to check for both
39+ */
40+ char f[gp_file_name_sizeof];
41+ const char *pipestr = "|";
42+ const size_t pipestrlen = strlen(pipestr);
43+ const size_t preflen = strlen(iodev->dname);
44+ const size_t nlen = strlen(fname);
45+ int code1;
46+
47+ if (preflen + nlen >= gp_file_name_sizeof)
48+ return_error(gs_error_invalidaccess);
49+
50+ memcpy(f, iodev->dname, preflen);
51+ memcpy(f + preflen, fname, nlen + 1);
52+
53+ code1 = gp_validate_path(mem, f, access);
54+
55+ memcpy(f, pipestr, pipestrlen);
56+ memcpy(f + pipestrlen, fname, nlen + 1);
57
58- if (gp_validate_path(mem, fname, access) != 0)
59+ if (code1 != 0 && gp_validate_path(mem, f, access) != 0 )
60 return gs_error_invalidfileaccess;
61
62 /*
63diff --git a/base/gp_mshdl.c b/base/gp_mshdl.c
64index 2b964ed74..8d87ceadc 100644
65--- a/base/gp_mshdl.c
66+++ b/base/gp_mshdl.c
67@@ -95,8 +95,17 @@ mswin_handle_fopen(gx_io_device * iodev, const char *fname, const char *access,
68 long hfile; /* Correct for Win32, may be wrong for Win64 */
69 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
70 gs_fs_list_t *fs = ctx->core->fs;
71+ char f[gp_file_name_sizeof];
72+ const size_t preflen = strlen(iodev->dname);
73+ const size_t nlen = strlen(fname);
74
75- if (gp_validate_path(mem, fname, access) != 0)
76+ if (preflen + nlen >= gp_file_name_sizeof)
77+ return_error(gs_error_invalidaccess);
78+
79+ memcpy(f, iodev->dname, preflen);
80+ memcpy(f + preflen, fname, nlen + 1);
81+
82+ if (gp_validate_path(mem, f, access) != 0)
83 return gs_error_invalidfileaccess;
84
85 /* First we try the open_handle method. */
86diff --git a/base/gp_msprn.c b/base/gp_msprn.c
87index ed4827968..746a974f7 100644
88--- a/base/gp_msprn.c
89+++ b/base/gp_msprn.c
90@@ -168,8 +168,16 @@ mswin_printer_fopen(gx_io_device * iodev, const char *fname, const char *access,
91 uintptr_t *ptid = &((tid_t *)(iodev->state))->tid;
92 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
93 gs_fs_list_t *fs = ctx->core->fs;
94+ const size_t preflen = strlen(iodev->dname);
95+ const size_t nlen = strlen(fname);
96
97- if (gp_validate_path(mem, fname, access) != 0)
98+ if (preflen + nlen >= gp_file_name_sizeof)
99+ return_error(gs_error_invalidaccess);
100+
101+ memcpy(pname, iodev->dname, preflen);
102+ memcpy(pname + preflen, fname, nlen + 1);
103+
104+ if (gp_validate_path(mem, pname, access) != 0)
105 return gs_error_invalidfileaccess;
106
107 /* First we try the open_printer method. */
108diff --git a/base/gp_os2pr.c b/base/gp_os2pr.c
109index f852c71fc..ba54cde66 100644
110--- a/base/gp_os2pr.c
111+++ b/base/gp_os2pr.c
112@@ -107,9 +107,20 @@ os2_printer_fopen(gx_io_device * iodev, const char *fname, const char *access,
113 FILE ** pfile, char *rfname, uint rnamelen)
114 {
115 os2_printer_t *pr = (os2_printer_t *)iodev->state;
116- char driver_name[256];
117+ char driver_name[gp_file_name_sizeof];
118 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
119 gs_fs_list_t *fs = ctx->core->fs;
120+ const size_t preflen = strlen(iodev->dname);
121+ const int size_t = strlen(fname);
122+
123+ if (preflen + nlen >= gp_file_name_sizeof)
124+ return_error(gs_error_invalidaccess);
125+
126+ memcpy(driver_name, iodev->dname, preflen);
127+ memcpy(driver_name + preflen, fname, nlen + 1);
128+
129+ if (gp_validate_path(mem, driver_name, access) != 0)
130+ return gs_error_invalidfileaccess;
131
132 /* First we try the open_printer method. */
133 /* Note that the loop condition here ensures we don't
134diff --git a/base/gslibctx.c b/base/gslibctx.c
135index 6dfed6cd5..318039fad 100644
136--- a/base/gslibctx.c
137+++ b/base/gslibctx.c
138@@ -655,82 +655,39 @@ rewrite_percent_specifiers(char *s)
139 int
140 gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
141 {
142- char *fp, f[gp_file_name_sizeof];
143- const int pipe = 124; /* ASCII code for '|' */
144- const int len = strlen(fname);
145- int i, code;
146+ char f[gp_file_name_sizeof];
147+ int code;
148
149 /* Be sure the string copy will fit */
150- if (len >= gp_file_name_sizeof)
151+ if (strlen(fname) >= gp_file_name_sizeof)
152 return gs_error_rangecheck;
153 strcpy(f, fname);
154- fp = f;
155 /* Try to rewrite any %d (or similar) in the string */
156 rewrite_percent_specifiers(f);
157- for (i = 0; i < len; i++) {
158- if (f[i] == pipe) {
159- fp = &f[i + 1];
160- /* Because we potentially have to check file permissions at two levels
161- for the output file (gx_device_open_output_file and the low level
162- fopen API, if we're using a pipe, we have to add both the full string,
163- (including the '|', and just the command to which we pipe - since at
164- the pipe_fopen(), the leading '|' has been stripped.
165- */
166- code = gs_add_control_path(mem, gs_permit_file_writing, f);
167- if (code < 0)
168- return code;
169- code = gs_add_control_path(mem, gs_permit_file_control, f);
170- if (code < 0)
171- return code;
172- break;
173- }
174- if (!IS_WHITESPACE(f[i]))
175- break;
176- }
177- code = gs_add_control_path(mem, gs_permit_file_control, fp);
178+
179+ code = gs_add_control_path(mem, gs_permit_file_control, f);
180 if (code < 0)
181 return code;
182- return gs_add_control_path(mem, gs_permit_file_writing, fp);
183+ return gs_add_control_path(mem, gs_permit_file_writing, f);
184 }
185
186 int
187 gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
188 {
189- char *fp, f[gp_file_name_sizeof];
190- const int pipe = 124; /* ASCII code for '|' */
191- const int len = strlen(fname);
192- int i, code;
193+ char f[gp_file_name_sizeof];
194+ int code;
195
196 /* Be sure the string copy will fit */
197- if (len >= gp_file_name_sizeof)
198+ if (strlen(fname) >= gp_file_name_sizeof)
199 return gs_error_rangecheck;
200 strcpy(f, fname);
201- fp = f;
202 /* Try to rewrite any %d (or similar) in the string */
203- for (i = 0; i < len; i++) {
204- if (f[i] == pipe) {
205- fp = &f[i + 1];
206- /* Because we potentially have to check file permissions at two levels
207- for the output file (gx_device_open_output_file and the low level
208- fopen API, if we're using a pipe, we have to add both the full string,
209- (including the '|', and just the command to which we pipe - since at
210- the pipe_fopen(), the leading '|' has been stripped.
211- */
212- code = gs_remove_control_path(mem, gs_permit_file_writing, f);
213- if (code < 0)
214- return code;
215- code = gs_remove_control_path(mem, gs_permit_file_control, f);
216- if (code < 0)
217- return code;
218- break;
219- }
220- if (!IS_WHITESPACE(f[i]))
221- break;
222- }
223- code = gs_remove_control_path(mem, gs_permit_file_control, fp);
224+ rewrite_percent_specifiers(f);
225+
226+ code = gs_remove_control_path(mem, gs_permit_file_control, f);
227 if (code < 0)
228 return code;
229- return gs_remove_control_path(mem, gs_permit_file_writing, fp);
230+ return gs_remove_control_path(mem, gs_permit_file_writing, f);
231 }
232
233 int
234--
2352.25.1
236
diff --git a/meta/recipes-extended/ghostscript/ghostscript_9.54.0.bb b/meta/recipes-extended/ghostscript/ghostscript_9.54.0.bb
index d4442a4908..28d064a1a8 100644
--- a/meta/recipes-extended/ghostscript/ghostscript_9.54.0.bb
+++ b/meta/recipes-extended/ghostscript/ghostscript_9.54.0.bb
@@ -34,6 +34,7 @@ SRC_URI_BASE = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/d
34 file://avoid-host-contamination.patch \ 34 file://avoid-host-contamination.patch \
35 file://mkdir-p.patch \ 35 file://mkdir-p.patch \
36 file://CVE-2021-45949.patch \ 36 file://CVE-2021-45949.patch \
37 file://CVE-2021-3781.patch \
37" 38"
38 39
39SRC_URI = "${SRC_URI_BASE} \ 40SRC_URI = "${SRC_URI_BASE} \