summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavide Gardenal <davidegarde2000@gmail.com>2022-03-25 17:46:30 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-03-31 21:09:33 +0100
commita27aa2316f383735d5c4cba7f7e502bff579979b (patch)
tree33c61bb6dd64663ce6fb868102faf00fa0c91416
parent4391ddecb2c5903a4c00d62646add0988a79c6d9 (diff)
downloadpoky-a27aa2316f383735d5c4cba7f7e502bff579979b.tar.gz
ghostscript: backport patch fix for CVE-2021-3781
Upstream advisory: https://ghostscript.com/blog/CVE-2021-3781.html Other than the CVE fix other two commits are backported to fit the patch. (From OE-Core rev: ce856e5e07589d49d5ff84b515c48735cc78cd01) Signed-off-by: Davide Gardenal <davide.gardenal@huawei.com> Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_1.patch121
-rw-r--r--meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_2.patch37
-rw-r--r--meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_3.patch238
-rw-r--r--meta/recipes-extended/ghostscript/ghostscript_9.52.bb3
4 files changed, 399 insertions, 0 deletions
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_1.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_1.patch
new file mode 100644
index 0000000000..033ba77f9a
--- /dev/null
+++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_1.patch
@@ -0,0 +1,121 @@
1From 3920a727fb19e19f597e518610ce2416d08cb75f Mon Sep 17 00:00:00 2001
2From: Chris Liddell <chris.liddell@artifex.com>
3Date: Thu, 20 Aug 2020 17:19:09 +0100
4Subject: [PATCH] Fix pdfwrite "%d" mode with file permissions
5
6Firstly, in gx_device_delete_output_file the iodev pointer was being passed
7to the delete_method incorrectly (passing a pointer to that pointer). Thus
8when we attempted to use that to confirm permission to delete the file, it
9crashed. Credit to Ken for finding that.
10
11Secondly, due to the way pdfwrite works, when running with an output file per
12page, it creates the current output file immediately it has completed writing
13the previous one. Thus, it has to delete that partial file on exit.
14
15Previously, the output file was not added to the "control" permission list,
16so an attempt to delete it would result in an error. So add the output file
17to the "control" as well as "write" list.
18
19CVE: CVE-2021-3781
20
21Upstream-Status: Backport:
22https://git.ghostscript.com/?p=ghostpdl.git;a=commit;f=base/gslibctx.c;h=3920a727fb19e19f597e518610ce2416d08cb75f
23
24Signed-off-by: Davide Gardenal <davide.gardenal@huawei.com>
25---
26 base/gsdevice.c | 2 +-
27 base/gslibctx.c | 20 ++++++++++++++------
28 2 files changed, 15 insertions(+), 7 deletions(-)
29
30diff --git a/base/gsdevice.c b/base/gsdevice.c
31index 913119495..ac78af93f 100644
32--- a/base/gsdevice.c
33+++ b/base/gsdevice.c
34@@ -1185,7 +1185,7 @@ int gx_device_delete_output_file(const gx_device * dev, const char *fname)
35 parsed.len = strlen(parsed.fname);
36 }
37 if (parsed.iodev)
38- code = parsed.iodev->procs.delete_file((gx_io_device *)(&parsed.iodev), (const char *)parsed.fname);
39+ code = parsed.iodev->procs.delete_file((gx_io_device *)(parsed.iodev), (const char *)parsed.fname);
40 else
41 code = gs_note_error(gs_error_invalidfileaccess);
42
43diff --git a/base/gslibctx.c b/base/gslibctx.c
44index d726c58b5..ff8fc895e 100644
45--- a/base/gslibctx.c
46+++ b/base/gslibctx.c
47@@ -647,7 +647,7 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
48 char *fp, f[gp_file_name_sizeof];
49 const int pipe = 124; /* ASCII code for '|' */
50 const int len = strlen(fname);
51- int i;
52+ int i, code;
53
54 /* Be sure the string copy will fit */
55 if (len >= gp_file_name_sizeof)
56@@ -658,8 +658,6 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
57 rewrite_percent_specifiers(f);
58 for (i = 0; i < len; i++) {
59 if (f[i] == pipe) {
60- int code;
61-
62 fp = &f[i + 1];
63 /* Because we potentially have to check file permissions at two levels
64 for the output file (gx_device_open_output_file and the low level
65@@ -671,10 +669,16 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
66 if (code < 0)
67 return code;
68 break;
69+ code = gs_add_control_path(mem, gs_permit_file_control, f);
70+ if (code < 0)
71+ return code;
72 }
73 if (!IS_WHITESPACE(f[i]))
74 break;
75 }
76+ code = gs_add_control_path(mem, gs_permit_file_control, fp);
77+ if (code < 0)
78+ return code;
79 return gs_add_control_path(mem, gs_permit_file_writing, fp);
80 }
81
82@@ -684,7 +688,7 @@ gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
83 char *fp, f[gp_file_name_sizeof];
84 const int pipe = 124; /* ASCII code for '|' */
85 const int len = strlen(fname);
86- int i;
87+ int i, code;
88
89 /* Be sure the string copy will fit */
90 if (len >= gp_file_name_sizeof)
91@@ -694,8 +698,6 @@ gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
92 /* Try to rewrite any %d (or similar) in the string */
93 for (i = 0; i < len; i++) {
94 if (f[i] == pipe) {
95- int code;
96-
97 fp = &f[i + 1];
98 /* Because we potentially have to check file permissions at two levels
99 for the output file (gx_device_open_output_file and the low level
100@@ -704,6 +706,9 @@ gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
101 the pipe_fopen(), the leading '|' has been stripped.
102 */
103 code = gs_remove_control_path(mem, gs_permit_file_writing, f);
104+ if (code < 0)
105+ return code;
106+ code = gs_remove_control_path(mem, gs_permit_file_control, f);
107 if (code < 0)
108 return code;
109 break;
110@@ -711,6 +716,9 @@ gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
111 if (!IS_WHITESPACE(f[i]))
112 break;
113 }
114+ code = gs_remove_control_path(mem, gs_permit_file_control, fp);
115+ if (code < 0)
116+ return code;
117 return gs_remove_control_path(mem, gs_permit_file_writing, fp);
118 }
119
120--
1212.25.1
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_2.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_2.patch
new file mode 100644
index 0000000000..beade79eef
--- /dev/null
+++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_2.patch
@@ -0,0 +1,37 @@
1From 9daf042fd7bb19e93388d89d9686a2fa4496f382 Mon Sep 17 00:00:00 2001
2From: Chris Liddell <chris.liddell@artifex.com>
3Date: Mon, 24 Aug 2020 09:24:31 +0100
4Subject: [PATCH] Coverity 361429: move "break" to correct place.
5
6We had to add the outputfile to the "control" file permission list (as well
7as write), but for the "pipe" case, I accidentally added the call after the
8break out of loop that checks for a pipe.
9
10CVE: CVE-2021-3781
11
12Upstream-Status: Backport:
13https://git.ghostscript.com/?p=ghostpdl.git;a=commit;f=base/gslibctx.c;h=9daf042fd7bb19e93388d89d9686a2fa4496f382
14
15Signed-off-by: Davide Gardenal <davide.gardenal@huawei.com>
16---
17 base/gslibctx.c | 2 +-
18 1 file changed, 1 insertion(+), 1 deletion(-)
19
20diff --git a/base/gslibctx.c b/base/gslibctx.c
21index ff8fc895e..63dfbe2e0 100644
22--- a/base/gslibctx.c
23+++ b/base/gslibctx.c
24@@ -668,10 +668,10 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
25 code = gs_add_control_path(mem, gs_permit_file_writing, f);
26 if (code < 0)
27 return code;
28- break;
29 code = gs_add_control_path(mem, gs_permit_file_control, f);
30 if (code < 0)
31 return code;
32+ break;
33 }
34 if (!IS_WHITESPACE(f[i]))
35 break;
36--
372.25.1
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_3.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_3.patch
new file mode 100644
index 0000000000..e3f9e81c45
--- /dev/null
+++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-3781_3.patch
@@ -0,0 +1,238 @@
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
18CVE: CVE-2021-3781
19
20Upstream-Status: Backport:
21https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=a9bd3dec9fde
22
23Signed-off-by: Davide Gardenal <davide.gardenal@huawei.com>
24---
25 base/gdevpipe.c | 22 +++++++++++++++-
26 base/gp_mshdl.c | 11 +++++++-
27 base/gp_msprn.c | 10 ++++++-
28 base/gp_os2pr.c | 13 +++++++++-
29 base/gslibctx.c | 69 ++++++++++---------------------------------------
30 5 files changed, 65 insertions(+), 60 deletions(-)
31
32diff --git a/base/gdevpipe.c b/base/gdevpipe.c
33index 96d71f5d8..5bdc485be 100644
34--- a/base/gdevpipe.c
35+++ b/base/gdevpipe.c
36@@ -72,8 +72,28 @@ pipe_fopen(gx_io_device * iodev, const char *fname, const char *access,
37 #else
38 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
39 gs_fs_list_t *fs = ctx->core->fs;
40+ /* The pipe device can be reached in two ways, explicltly with %pipe%
41+ or implicitly with "|", so we have to check for both
42+ */
43+ char f[gp_file_name_sizeof];
44+ const char *pipestr = "|";
45+ const size_t pipestrlen = strlen(pipestr);
46+ const size_t preflen = strlen(iodev->dname);
47+ const size_t nlen = strlen(fname);
48+ int code1;
49+
50+ if (preflen + nlen >= gp_file_name_sizeof)
51+ return_error(gs_error_invalidaccess);
52+
53+ memcpy(f, iodev->dname, preflen);
54+ memcpy(f + preflen, fname, nlen + 1);
55+
56+ code1 = gp_validate_path(mem, f, access);
57+
58+ memcpy(f, pipestr, pipestrlen);
59+ memcpy(f + pipestrlen, fname, nlen + 1);
60
61- if (gp_validate_path(mem, fname, access) != 0)
62+ if (code1 != 0 && gp_validate_path(mem, f, access) != 0 )
63 return gs_error_invalidfileaccess;
64
65 /*
66diff --git a/base/gp_mshdl.c b/base/gp_mshdl.c
67index 2b964ed74..8d87ceadc 100644
68--- a/base/gp_mshdl.c
69+++ b/base/gp_mshdl.c
70@@ -95,8 +95,17 @@ mswin_handle_fopen(gx_io_device * iodev, const char *fname, const char *access,
71 long hfile; /* Correct for Win32, may be wrong for Win64 */
72 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
73 gs_fs_list_t *fs = ctx->core->fs;
74+ char f[gp_file_name_sizeof];
75+ const size_t preflen = strlen(iodev->dname);
76+ const size_t nlen = strlen(fname);
77
78- if (gp_validate_path(mem, fname, access) != 0)
79+ if (preflen + nlen >= gp_file_name_sizeof)
80+ return_error(gs_error_invalidaccess);
81+
82+ memcpy(f, iodev->dname, preflen);
83+ memcpy(f + preflen, fname, nlen + 1);
84+
85+ if (gp_validate_path(mem, f, access) != 0)
86 return gs_error_invalidfileaccess;
87
88 /* First we try the open_handle method. */
89diff --git a/base/gp_msprn.c b/base/gp_msprn.c
90index ed4827968..746a974f7 100644
91--- a/base/gp_msprn.c
92+++ b/base/gp_msprn.c
93@@ -168,8 +168,16 @@ mswin_printer_fopen(gx_io_device * iodev, const char *fname, const char *access,
94 unsigned long *ptid = &((tid_t *)(iodev->state))->tid;
95 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
96 gs_fs_list_t *fs = ctx->core->fs;
97+ const size_t preflen = strlen(iodev->dname);
98+ const size_t nlen = strlen(fname);
99
100- if (gp_validate_path(mem, fname, access) != 0)
101+ if (preflen + nlen >= gp_file_name_sizeof)
102+ return_error(gs_error_invalidaccess);
103+
104+ memcpy(pname, iodev->dname, preflen);
105+ memcpy(pname + preflen, fname, nlen + 1);
106+
107+ if (gp_validate_path(mem, pname, access) != 0)
108 return gs_error_invalidfileaccess;
109
110 /* First we try the open_printer method. */
111diff --git a/base/gp_os2pr.c b/base/gp_os2pr.c
112index f852c71fc..ba54cde66 100644
113--- a/base/gp_os2pr.c
114+++ b/base/gp_os2pr.c
115@@ -107,9 +107,20 @@ os2_printer_fopen(gx_io_device * iodev, const char *fname, const char *access,
116 FILE ** pfile, char *rfname, uint rnamelen)
117 {
118 os2_printer_t *pr = (os2_printer_t *)iodev->state;
119- char driver_name[256];
120+ char driver_name[gp_file_name_sizeof];
121 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
122 gs_fs_list_t *fs = ctx->core->fs;
123+ const size_t preflen = strlen(iodev->dname);
124+ const int size_t = strlen(fname);
125+
126+ if (preflen + nlen >= gp_file_name_sizeof)
127+ return_error(gs_error_invalidaccess);
128+
129+ memcpy(driver_name, iodev->dname, preflen);
130+ memcpy(driver_name + preflen, fname, nlen + 1);
131+
132+ if (gp_validate_path(mem, driver_name, access) != 0)
133+ return gs_error_invalidfileaccess;
134
135 /* First we try the open_printer method. */
136 /* Note that the loop condition here ensures we don't
137diff --git a/base/gslibctx.c b/base/gslibctx.c
138index 6dfed6cd5..318039fad 100644
139--- a/base/gslibctx.c
140+++ b/base/gslibctx.c
141@@ -655,82 +655,39 @@ rewrite_percent_specifiers(char *s)
142 int
143 gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
144 {
145- char *fp, f[gp_file_name_sizeof];
146- const int pipe = 124; /* ASCII code for '|' */
147- const int len = strlen(fname);
148- int i, code;
149+ char f[gp_file_name_sizeof];
150+ int code;
151
152 /* Be sure the string copy will fit */
153- if (len >= gp_file_name_sizeof)
154+ if (strlen(fname) >= gp_file_name_sizeof)
155 return gs_error_rangecheck;
156 strcpy(f, fname);
157- fp = f;
158 /* Try to rewrite any %d (or similar) in the string */
159 rewrite_percent_specifiers(f);
160- for (i = 0; i < len; i++) {
161- if (f[i] == pipe) {
162- fp = &f[i + 1];
163- /* Because we potentially have to check file permissions at two levels
164- for the output file (gx_device_open_output_file and the low level
165- fopen API, if we're using a pipe, we have to add both the full string,
166- (including the '|', and just the command to which we pipe - since at
167- the pipe_fopen(), the leading '|' has been stripped.
168- */
169- code = gs_add_control_path(mem, gs_permit_file_writing, f);
170- if (code < 0)
171- return code;
172- code = gs_add_control_path(mem, gs_permit_file_control, f);
173- if (code < 0)
174- return code;
175- break;
176- }
177- if (!IS_WHITESPACE(f[i]))
178- break;
179- }
180- code = gs_add_control_path(mem, gs_permit_file_control, fp);
181+
182+ code = gs_add_control_path(mem, gs_permit_file_control, f);
183 if (code < 0)
184 return code;
185- return gs_add_control_path(mem, gs_permit_file_writing, fp);
186+ return gs_add_control_path(mem, gs_permit_file_writing, f);
187 }
188
189 int
190 gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
191 {
192- char *fp, f[gp_file_name_sizeof];
193- const int pipe = 124; /* ASCII code for '|' */
194- const int len = strlen(fname);
195- int i, code;
196+ char f[gp_file_name_sizeof];
197+ int code;
198
199 /* Be sure the string copy will fit */
200- if (len >= gp_file_name_sizeof)
201+ if (strlen(fname) >= gp_file_name_sizeof)
202 return gs_error_rangecheck;
203 strcpy(f, fname);
204- fp = f;
205 /* Try to rewrite any %d (or similar) in the string */
206- for (i = 0; i < len; i++) {
207- if (f[i] == pipe) {
208- fp = &f[i + 1];
209- /* Because we potentially have to check file permissions at two levels
210- for the output file (gx_device_open_output_file and the low level
211- fopen API, if we're using a pipe, we have to add both the full string,
212- (including the '|', and just the command to which we pipe - since at
213- the pipe_fopen(), the leading '|' has been stripped.
214- */
215- code = gs_remove_control_path(mem, gs_permit_file_writing, f);
216- if (code < 0)
217- return code;
218- code = gs_remove_control_path(mem, gs_permit_file_control, f);
219- if (code < 0)
220- return code;
221- break;
222- }
223- if (!IS_WHITESPACE(f[i]))
224- break;
225- }
226- code = gs_remove_control_path(mem, gs_permit_file_control, fp);
227+ rewrite_percent_specifiers(f);
228+
229+ code = gs_remove_control_path(mem, gs_permit_file_control, f);
230 if (code < 0)
231 return code;
232- return gs_remove_control_path(mem, gs_permit_file_writing, fp);
233+ return gs_remove_control_path(mem, gs_permit_file_writing, f);
234 }
235
236 int
237--
2382.25.1
diff --git a/meta/recipes-extended/ghostscript/ghostscript_9.52.bb b/meta/recipes-extended/ghostscript/ghostscript_9.52.bb
index 310c4f6d24..a829d4b4ae 100644
--- a/meta/recipes-extended/ghostscript/ghostscript_9.52.bb
+++ b/meta/recipes-extended/ghostscript/ghostscript_9.52.bb
@@ -36,6 +36,9 @@ SRC_URI_BASE = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/d
36 file://CVE-2020-15900.patch \ 36 file://CVE-2020-15900.patch \
37 file://check-stack-limits-after-function-evalution.patch \ 37 file://check-stack-limits-after-function-evalution.patch \
38 file://CVE-2021-45949.patch \ 38 file://CVE-2021-45949.patch \
39 file://CVE-2021-3781_1.patch \
40 file://CVE-2021-3781_2.patch \
41 file://CVE-2021-3781_3.patch \
39" 42"
40 43
41SRC_URI = "${SRC_URI_BASE} \ 44SRC_URI = "${SRC_URI_BASE} \