diff options
Diffstat (limited to 'meta/recipes-extended/ghostscript/ghostscript')
12 files changed, 1035 insertions, 0 deletions
diff --git a/meta/recipes-extended/ghostscript/ghostscript/0001-Bug-706897-Copy-pcx-buffer-overrun-fix-from-devices-.patch b/meta/recipes-extended/ghostscript/ghostscript/0001-Bug-706897-Copy-pcx-buffer-overrun-fix-from-devices-.patch new file mode 100644 index 0000000000..91b9f6df50 --- /dev/null +++ b/meta/recipes-extended/ghostscript/ghostscript/0001-Bug-706897-Copy-pcx-buffer-overrun-fix-from-devices-.patch | |||
@@ -0,0 +1,31 @@ | |||
1 | From d81b82c70bc1fb9991bb95f1201abb5dea55f57f Mon Sep 17 00:00:00 2001 | ||
2 | From: Chris Liddell <chris.liddell@artifex.com> | ||
3 | Date: Mon, 17 Jul 2023 14:06:37 +0100 | ||
4 | Subject: [PATCH] Bug 706897: Copy pcx buffer overrun fix from | ||
5 | devices/gdevpcx.c | ||
6 | |||
7 | Bounds check the buffer, before dereferencing the pointer. | ||
8 | |||
9 | Upstream-Status: Backport [https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=d81b82c70bc1fb9991bb95f1201abb5dea55f57f] | ||
10 | CVE: CVE-2023-38559 | ||
11 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
12 | --- | ||
13 | base/gdevdevn.c | 2 +- | ||
14 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/base/gdevdevn.c b/base/gdevdevn.c | ||
17 | index 3b019d6..2888776 100644 | ||
18 | --- a/base/gdevdevn.c | ||
19 | +++ b/base/gdevdevn.c | ||
20 | @@ -1980,7 +1980,7 @@ devn_pcx_write_rle(const byte * from, const byte * end, int step, gp_file * file | ||
21 | byte data = *from; | ||
22 | |||
23 | from += step; | ||
24 | - if (data != *from || from == end) { | ||
25 | + if (from >= end || data != *from) { | ||
26 | if (data >= 0xc0) | ||
27 | gp_fputc(0xc1, file); | ||
28 | } else { | ||
29 | -- | ||
30 | 2.25.1 | ||
31 | |||
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2020-36773.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2020-36773.patch new file mode 100644 index 0000000000..ea8bf26f3f --- /dev/null +++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2020-36773.patch | |||
@@ -0,0 +1,109 @@ | |||
1 | From 8c7bd787defa071c96289b7da9397f673fddb874 Mon Sep 17 00:00:00 2001 | ||
2 | From: Ken Sharp <ken.sharp@artifex.com> | ||
3 | Date: Wed, 20 May 2020 16:02:07 +0100 | ||
4 | Subject: [PATCH] txtwrite - address memory problems | ||
5 | |||
6 | Bug #702229 " txtwrite: use after free in 9.51 on some files (regression from 9.50)" | ||
7 | Also bug #702346 and the earlier report #701877. | ||
8 | |||
9 | The problems occur because its possible for a single character code in | ||
10 | a PDF file to map to more than a single Unicode code point. In the case | ||
11 | of the file for 701877 the character code maps to 'f' and 'i' (it is an | ||
12 | fi ligature). | ||
13 | |||
14 | The code should deal with this, but we need to ensure we are using the | ||
15 | correct index. In addition, if we do get more Unicode code points than | ||
16 | we expected, we need to set the widths of the 'extra' code points to | ||
17 | zero (we only want to consider the width of the original character). | ||
18 | |||
19 | This does mean increasing the size of the Widths array to cater for | ||
20 | the possibility of more entries on output than there were on input. | ||
21 | |||
22 | While working on it I noticed that the Unicode remapping on little- | ||
23 | endian machines was reversing the order of the Unicode values, when | ||
24 | there was more than a single code point returned, so fixed that at | ||
25 | the same time. | ||
26 | |||
27 | Upstream-Status: Backport [https://git.ghostscript.com/?p=ghostpdl.git;h=8c7bd787defa071c96289b7da9397f673fddb874] | ||
28 | CVE: CVE-2020-36773 | ||
29 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
30 | --- | ||
31 | devices/vector/gdevtxtw.c | 26 ++++++++++++++++---------- | ||
32 | 1 file changed, 16 insertions(+), 10 deletions(-) | ||
33 | |||
34 | diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c | ||
35 | index 87f9355..bddce5a 100644 | ||
36 | --- a/devices/vector/gdevtxtw.c | ||
37 | +++ b/devices/vector/gdevtxtw.c | ||
38 | @@ -1812,11 +1812,11 @@ static int get_unicode(textw_text_enum_t *penum, gs_font *font, gs_glyph glyph, | ||
39 | #else | ||
40 | b = (char *)Buffer; | ||
41 | u = (char *)unicode; | ||
42 | - while (l >= 0) { | ||
43 | - *b++ = *(u + l); | ||
44 | - l--; | ||
45 | - } | ||
46 | |||
47 | + for (l=0;l<length;l+=2, u+=2){ | ||
48 | + *b++ = *(u+1); | ||
49 | + *b++ = *u; | ||
50 | + } | ||
51 | #endif | ||
52 | gs_free_object(penum->dev->memory, unicode, "free temporary unicode buffer"); | ||
53 | return length / sizeof(short); | ||
54 | @@ -1963,7 +1963,7 @@ txtwrite_process_plain_text(gs_text_enum_t *pte) | ||
55 | &penum->text_state->matrix, &wanted); | ||
56 | pte->returned.total_width.x += wanted.x; | ||
57 | pte->returned.total_width.y += wanted.y; | ||
58 | - penum->Widths[pte->index - 1] = wanted.x; | ||
59 | + penum->Widths[penum->TextBufferIndex] = wanted.x; | ||
60 | |||
61 | if (pte->text.operation & TEXT_ADD_TO_ALL_WIDTHS) { | ||
62 | gs_point tpt; | ||
63 | @@ -1984,8 +1984,14 @@ txtwrite_process_plain_text(gs_text_enum_t *pte) | ||
64 | pte->returned.total_width.x += dpt.x; | ||
65 | pte->returned.total_width.y += dpt.y; | ||
66 | |||
67 | - penum->TextBufferIndex += get_unicode(penum, (gs_font *)pte->orig_font, glyph, ch, &penum->TextBuffer[penum->TextBufferIndex]); | ||
68 | - penum->Widths[pte->index - 1] += dpt.x; | ||
69 | + penum->Widths[penum->TextBufferIndex] += dpt.x; | ||
70 | + code = get_unicode(penum, (gs_font *)pte->orig_font, glyph, ch, &penum->TextBuffer[penum->TextBufferIndex]); | ||
71 | + /* If a single text code returned multiple Unicode values, then we need to set the | ||
72 | + * 'extra' code points' widths to 0. | ||
73 | + */ | ||
74 | + if (code > 1) | ||
75 | + memset(&penum->Widths[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float)); | ||
76 | + penum->TextBufferIndex += code; | ||
77 | } | ||
78 | return 0; | ||
79 | } | ||
80 | @@ -2123,7 +2129,7 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum) | ||
81 | if (!penum->text_state->Widths) | ||
82 | return gs_note_error(gs_error_VMerror); | ||
83 | memset(penum->text_state->Widths, 0x00, penum->TextBufferIndex * sizeof(float)); | ||
84 | - memcpy(penum->text_state->Widths, penum->Widths, penum->text.size * sizeof(float)); | ||
85 | + memcpy(penum->text_state->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float)); | ||
86 | |||
87 | unsorted_entry->Unicode_Text = (unsigned short *)gs_malloc(tdev->memory->stable_memory, | ||
88 | penum->TextBufferIndex, sizeof(unsigned short), "txtwrite alloc sorted text buffer"); | ||
89 | @@ -2136,7 +2142,7 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum) | ||
90 | if (!unsorted_entry->Widths) | ||
91 | return gs_note_error(gs_error_VMerror); | ||
92 | memset(unsorted_entry->Widths, 0x00, penum->TextBufferIndex * sizeof(float)); | ||
93 | - memcpy(unsorted_entry->Widths, penum->Widths, penum->text.size * sizeof(float)); | ||
94 | + memcpy(unsorted_entry->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float)); | ||
95 | |||
96 | unsorted_entry->FontName = (char *)gs_malloc(tdev->memory->stable_memory, | ||
97 | (strlen(penum->text_state->FontName) + 1), sizeof(unsigned char), "txtwrite alloc sorted text buffer"); | ||
98 | @@ -2192,7 +2198,7 @@ textw_text_process(gs_text_enum_t *pte) | ||
99 | if (!penum->TextBuffer) | ||
100 | return gs_note_error(gs_error_VMerror); | ||
101 | penum->Widths = (float *)gs_malloc(tdev->memory->stable_memory, | ||
102 | - pte->text.size, sizeof(float), "txtwrite temporary widths array"); | ||
103 | + pte->text.size * 4, sizeof(float), "txtwrite temporary widths array"); | ||
104 | if (!penum->Widths) | ||
105 | return gs_note_error(gs_error_VMerror); | ||
106 | } | ||
107 | -- | ||
108 | 2.25.1 | ||
109 | |||
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 @@ | |||
1 | From 3920a727fb19e19f597e518610ce2416d08cb75f Mon Sep 17 00:00:00 2001 | ||
2 | From: Chris Liddell <chris.liddell@artifex.com> | ||
3 | Date: Thu, 20 Aug 2020 17:19:09 +0100 | ||
4 | Subject: [PATCH] Fix pdfwrite "%d" mode with file permissions | ||
5 | |||
6 | Firstly, in gx_device_delete_output_file the iodev pointer was being passed | ||
7 | to the delete_method incorrectly (passing a pointer to that pointer). Thus | ||
8 | when we attempted to use that to confirm permission to delete the file, it | ||
9 | crashed. Credit to Ken for finding that. | ||
10 | |||
11 | Secondly, due to the way pdfwrite works, when running with an output file per | ||
12 | page, it creates the current output file immediately it has completed writing | ||
13 | the previous one. Thus, it has to delete that partial file on exit. | ||
14 | |||
15 | Previously, the output file was not added to the "control" permission list, | ||
16 | so an attempt to delete it would result in an error. So add the output file | ||
17 | to the "control" as well as "write" list. | ||
18 | |||
19 | CVE: CVE-2021-3781 | ||
20 | |||
21 | Upstream-Status: Backport: | ||
22 | https://git.ghostscript.com/?p=ghostpdl.git;a=commit;f=base/gslibctx.c;h=3920a727fb19e19f597e518610ce2416d08cb75f | ||
23 | |||
24 | Signed-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 | |||
30 | diff --git a/base/gsdevice.c b/base/gsdevice.c | ||
31 | index 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 | |||
43 | diff --git a/base/gslibctx.c b/base/gslibctx.c | ||
44 | index 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 | -- | ||
121 | 2.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 @@ | |||
1 | From 9daf042fd7bb19e93388d89d9686a2fa4496f382 Mon Sep 17 00:00:00 2001 | ||
2 | From: Chris Liddell <chris.liddell@artifex.com> | ||
3 | Date: Mon, 24 Aug 2020 09:24:31 +0100 | ||
4 | Subject: [PATCH] Coverity 361429: move "break" to correct place. | ||
5 | |||
6 | We had to add the outputfile to the "control" file permission list (as well | ||
7 | as write), but for the "pipe" case, I accidentally added the call after the | ||
8 | break out of loop that checks for a pipe. | ||
9 | |||
10 | CVE: CVE-2021-3781 | ||
11 | |||
12 | Upstream-Status: Backport: | ||
13 | https://git.ghostscript.com/?p=ghostpdl.git;a=commit;f=base/gslibctx.c;h=9daf042fd7bb19e93388d89d9686a2fa4496f382 | ||
14 | |||
15 | Signed-off-by: Davide Gardenal <davide.gardenal@huawei.com> | ||
16 | --- | ||
17 | base/gslibctx.c | 2 +- | ||
18 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
19 | |||
20 | diff --git a/base/gslibctx.c b/base/gslibctx.c | ||
21 | index 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 | -- | ||
37 | 2.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 @@ | |||
1 | From a9bd3dec9fde03327a4a2c69dad1036bf9632e20 Mon Sep 17 00:00:00 2001 | ||
2 | From: Chris Liddell <chris.liddell@artifex.com> | ||
3 | Date: Tue, 7 Sep 2021 20:36:12 +0100 | ||
4 | Subject: [PATCH] Bug 704342: Include device specifier strings in access | ||
5 | validation | ||
6 | |||
7 | for the "%pipe%", %handle%" and %printer% io devices. | ||
8 | |||
9 | We previously validated only the part after the "%pipe%" Postscript device | ||
10 | specifier, but this proved insufficient. | ||
11 | |||
12 | This rebuilds the original file name string, and validates it complete. The | ||
13 | slight complication for "%pipe%" is it can be reached implicitly using | ||
14 | "|" so we have to check both prefixes. | ||
15 | |||
16 | Addresses CVE-2021-3781 | ||
17 | |||
18 | CVE: CVE-2021-3781 | ||
19 | |||
20 | Upstream-Status: Backport: | ||
21 | https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=a9bd3dec9fde | ||
22 | |||
23 | Signed-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 | |||
32 | diff --git a/base/gdevpipe.c b/base/gdevpipe.c | ||
33 | index 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 | /* | ||
66 | diff --git a/base/gp_mshdl.c b/base/gp_mshdl.c | ||
67 | index 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. */ | ||
89 | diff --git a/base/gp_msprn.c b/base/gp_msprn.c | ||
90 | index 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. */ | ||
111 | diff --git a/base/gp_os2pr.c b/base/gp_os2pr.c | ||
112 | index 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 | ||
137 | diff --git a/base/gslibctx.c b/base/gslibctx.c | ||
138 | index 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 | -- | ||
238 | 2.25.1 | ||
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-45949.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-45949.patch new file mode 100644 index 0000000000..f312f89e04 --- /dev/null +++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2021-45949.patch | |||
@@ -0,0 +1,65 @@ | |||
1 | From 6643ff0cb837db3eade489ffff21e3e92eee2ae0 Mon Sep 17 00:00:00 2001 | ||
2 | From: Chris Liddell <chris.liddell@artifex.com> | ||
3 | Date: Fri, 28 Jan 2022 08:21:19 +0000 | ||
4 | Subject: [PATCH] [PATCH] Bug 703902: Fix op stack management in | ||
5 | sampled_data_continue() | ||
6 | |||
7 | Replace pop() (which does no checking, and doesn't handle stack extension | ||
8 | blocks) with ref_stack_pop() which does do all that. | ||
9 | |||
10 | We still use pop() in one case (it's faster), but we have to later use | ||
11 | ref_stack_pop() before calling sampled_data_sample() which also accesses the | ||
12 | op stack. | ||
13 | |||
14 | Fixes: | ||
15 | https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=34675 | ||
16 | |||
17 | Upstream-Status: Backported [https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=2a3129365d3bc0d4a41f107ef175920d1505d1f7] | ||
18 | CVE: CVE-2021-45949 | ||
19 | Signed-off-by: Minjae Kim <flowergom@gmail.com> | ||
20 | --- | ||
21 | psi/zfsample.c | 13 ++++++++----- | ||
22 | 1 file changed, 8 insertions(+), 5 deletions(-) | ||
23 | |||
24 | diff --git a/psi/zfsample.c b/psi/zfsample.c | ||
25 | index 0023fa4..f84671f 100644 | ||
26 | --- a/psi/zfsample.c | ||
27 | +++ b/psi/zfsample.c | ||
28 | @@ -534,14 +534,17 @@ sampled_data_continue(i_ctx_t *i_ctx_p) | ||
29 | data_ptr[bps * i + j] = (byte)(cv >> ((bps - 1 - j) * 8)); /* MSB first */ | ||
30 | } | ||
31 | pop(num_out); /* Move op to base of result values */ | ||
32 | - | ||
33 | + /* From here on, we have to use ref_stack_pop() rather than pop() | ||
34 | + so that it handles stack extension blocks properly, before calling | ||
35 | + sampled_data_sample() which also uses the op stack. | ||
36 | + */ | ||
37 | /* Check if we are done collecting data. */ | ||
38 | |||
39 | if (increment_cube_indexes(params, penum->indexes)) { | ||
40 | if (stack_depth_adjust == 0) | ||
41 | - pop(O_STACK_PAD); /* Remove spare stack space */ | ||
42 | + ref_stack_pop(&o_stack, O_STACK_PAD); /* Remove spare stack space */ | ||
43 | else | ||
44 | - pop(stack_depth_adjust - num_out); | ||
45 | + ref_stack_pop(&o_stack, stack_depth_adjust - num_out); | ||
46 | /* Execute the closing procedure, if given */ | ||
47 | code = 0; | ||
48 | if (esp_finish_proc != 0) | ||
49 | @@ -554,11 +557,11 @@ sampled_data_continue(i_ctx_t *i_ctx_p) | ||
50 | if ((O_STACK_PAD - stack_depth_adjust) < 0) { | ||
51 | stack_depth_adjust = -(O_STACK_PAD - stack_depth_adjust); | ||
52 | check_op(stack_depth_adjust); | ||
53 | - pop(stack_depth_adjust); | ||
54 | + ref_stack_pop(&o_stack, stack_depth_adjust); | ||
55 | } | ||
56 | else { | ||
57 | check_ostack(O_STACK_PAD - stack_depth_adjust); | ||
58 | - push(O_STACK_PAD - stack_depth_adjust); | ||
59 | + ref_stack_push(&o_stack, O_STACK_PAD - stack_depth_adjust); | ||
60 | for (i=0;i<O_STACK_PAD - stack_depth_adjust;i++) | ||
61 | make_null(op - i); | ||
62 | } | ||
63 | -- | ||
64 | 2.17.1 | ||
65 | |||
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-28879.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-28879.patch new file mode 100644 index 0000000000..852f2459f7 --- /dev/null +++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-28879.patch | |||
@@ -0,0 +1,54 @@ | |||
1 | From 37ed5022cecd584de868933b5b60da2e995b3179 Mon Sep 17 00:00:00 2001 | ||
2 | From: Ken Sharp <ken.sharp@artifex.com> | ||
3 | Date: Fri, 24 Mar 2023 13:19:57 +0000 | ||
4 | Subject: [PATCH] Graphics library - prevent buffer overrun in (T)BCP encoding | ||
5 | |||
6 | Bug #706494 "Buffer Overflow in s_xBCPE_process" | ||
7 | |||
8 | As described in detail in the bug report, if the write buffer is filled | ||
9 | to one byte less than full, and we then try to write an escaped | ||
10 | character, we overrun the buffer because we don't check before | ||
11 | writing two bytes to it. | ||
12 | |||
13 | This just checks if we have two bytes before starting to write an | ||
14 | escaped character and exits if we don't (replacing the consumed byte | ||
15 | of the input). | ||
16 | |||
17 | Up for further discussion; why do we even permit a BCP encoding filter | ||
18 | anyway ? I think we should remove this, at least when SAFER is true. | ||
19 | |||
20 | Upstream-Status: Backport [https://git.ghostscript.com/?p=ghostpdl.git;h=37ed5022cecd584de868933b5b60da2e995b3179] | ||
21 | CVE: CVE-2023-28879 | ||
22 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
23 | --- | ||
24 | base/sbcp.c | 10 +++++++++- | ||
25 | 1 file changed, 9 insertions(+), 1 deletion(-) | ||
26 | |||
27 | diff --git a/base/sbcp.c b/base/sbcp.c | ||
28 | index 6b0383c..90784b5 100644 | ||
29 | --- a/base/sbcp.c | ||
30 | +++ b/base/sbcp.c | ||
31 | @@ -1,4 +1,4 @@ | ||
32 | -/* Copyright (C) 2001-2019 Artifex Software, Inc. | ||
33 | +/* Copyright (C) 2001-2023 Artifex Software, Inc. | ||
34 | All Rights Reserved. | ||
35 | |||
36 | This software is provided AS-IS with no warranty, either express or | ||
37 | @@ -50,6 +50,14 @@ s_xBCPE_process(stream_state * st, stream_cursor_read * pr, | ||
38 | byte ch = *++p; | ||
39 | |||
40 | if (ch <= 31 && escaped[ch]) { | ||
41 | + /* Make sure we have space to store two characters in the write buffer, | ||
42 | + * if we don't then exit without consuming the input character, we'll process | ||
43 | + * that on the next time round. | ||
44 | + */ | ||
45 | + if (pw->limit - q < 2) { | ||
46 | + p--; | ||
47 | + break; | ||
48 | + } | ||
49 | if (p == rlimit) { | ||
50 | p--; | ||
51 | break; | ||
52 | -- | ||
53 | 2.25.1 | ||
54 | |||
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-36664-1.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-36664-1.patch new file mode 100644 index 0000000000..a3bbe958eb --- /dev/null +++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-36664-1.patch | |||
@@ -0,0 +1,145 @@ | |||
1 | From 5e65eeae225c7d02d447de5abaf4a8e6d234fcea Mon Sep 17 00:00:00 2001 | ||
2 | From: Chris Liddell <chris.liddell@artifex.com> | ||
3 | Date: Wed, 7 Jun 2023 10:23:06 +0100 | ||
4 | Subject: [PATCH] Bug 706761: Don't "reduce" %pipe% file names for permission validation | ||
5 | |||
6 | For regular file names, we try to simplfy relative paths before we use them. | ||
7 | |||
8 | Because the %pipe% device can, effectively, accept command line calls, we | ||
9 | shouldn't be simplifying that string, because the command line syntax can end | ||
10 | up confusing the path simplifying code. That can result in permitting a pipe | ||
11 | command which does not match what was originally permitted. | ||
12 | |||
13 | Special case "%pipe" in the validation code so we always deal with the entire | ||
14 | string. | ||
15 | |||
16 | Upstream-Status: Backport [https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=505eab7782b429017eb434b2b95120855f2b0e3c] | ||
17 | CVE: CVE-2023-36664 | ||
18 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
19 | --- | ||
20 | base/gpmisc.c | 31 +++++++++++++++++++-------- | ||
21 | base/gslibctx.c | 56 ++++++++++++++++++++++++++++++++++++------------- | ||
22 | 2 files changed, 64 insertions(+), 23 deletions(-) | ||
23 | |||
24 | diff --git a/base/gpmisc.c b/base/gpmisc.c | ||
25 | index c4fffae..09ac6b3 100644 | ||
26 | --- a/base/gpmisc.c | ||
27 | +++ b/base/gpmisc.c | ||
28 | @@ -1046,16 +1046,29 @@ gp_validate_path_len(const gs_memory_t *mem, | ||
29 | && !memcmp(path + cdirstrl, dirsepstr, dirsepstrl)) { | ||
30 | prefix_len = 0; | ||
31 | } | ||
32 | - rlen = len+1; | ||
33 | - bufferfull = (char *)gs_alloc_bytes(mem->thread_safe_memory, rlen + prefix_len, "gp_validate_path"); | ||
34 | - if (bufferfull == NULL) | ||
35 | - return gs_error_VMerror; | ||
36 | - | ||
37 | - buffer = bufferfull + prefix_len; | ||
38 | - if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success) | ||
39 | - return gs_error_invalidfileaccess; | ||
40 | - buffer[rlen] = 0; | ||
41 | |||
42 | + /* "%pipe%" do not follow the normal rules for path definitions, so we | ||
43 | + don't "reduce" them to avoid unexpected results | ||
44 | + */ | ||
45 | + if (len > 5 && memcmp(path, "%pipe", 5) != 0) { | ||
46 | + bufferfull = buffer = (char *)gs_alloc_bytes(mem->thread_safe_memory, len + 1, "gp_validate_path"); | ||
47 | + if (buffer == NULL) | ||
48 | + return gs_error_VMerror; | ||
49 | + memcpy(buffer, path, len); | ||
50 | + buffer[len] = 0; | ||
51 | + rlen = len; | ||
52 | + } | ||
53 | + else { | ||
54 | + rlen = len+1; | ||
55 | + bufferfull = (char *)gs_alloc_bytes(mem->thread_safe_memory, rlen + prefix_len, "gp_validate_path"); | ||
56 | + if (bufferfull == NULL) | ||
57 | + return gs_error_VMerror; | ||
58 | + | ||
59 | + buffer = bufferfull + prefix_len; | ||
60 | + if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success) | ||
61 | + return gs_error_invalidfileaccess; | ||
62 | + buffer[rlen] = 0; | ||
63 | + } | ||
64 | while (1) { | ||
65 | switch (mode[0]) | ||
66 | { | ||
67 | diff --git a/base/gslibctx.c b/base/gslibctx.c | ||
68 | index 20c5eee..355c0e3 100644 | ||
69 | --- a/base/gslibctx.c | ||
70 | +++ b/base/gslibctx.c | ||
71 | @@ -719,14 +719,28 @@ gs_add_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const ch | ||
72 | return gs_error_rangecheck; | ||
73 | } | ||
74 | |||
75 | - rlen = len+1; | ||
76 | - buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gp_validate_path"); | ||
77 | - if (buffer == NULL) | ||
78 | - return gs_error_VMerror; | ||
79 | + /* "%pipe%" do not follow the normal rules for path definitions, so we | ||
80 | + don't "reduce" them to avoid unexpected results | ||
81 | + */ | ||
82 | + if (len > 5 && memcmp(path, "%pipe", 5) != 0) { | ||
83 | + buffer = (char *)gs_alloc_bytes(core->memory, len + 1, "gs_add_control_path_len"); | ||
84 | + if (buffer == NULL) | ||
85 | + return gs_error_VMerror; | ||
86 | + memcpy(buffer, path, len); | ||
87 | + buffer[len] = 0; | ||
88 | + rlen = len; | ||
89 | + } | ||
90 | + else { | ||
91 | + rlen = len + 1; | ||
92 | |||
93 | - if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success) | ||
94 | - return gs_error_invalidfileaccess; | ||
95 | - buffer[rlen] = 0; | ||
96 | + buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gs_add_control_path_len"); | ||
97 | + if (buffer == NULL) | ||
98 | + return gs_error_VMerror; | ||
99 | + | ||
100 | + if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success) | ||
101 | + return gs_error_invalidfileaccess; | ||
102 | + buffer[rlen] = 0; | ||
103 | + } | ||
104 | |||
105 | n = control->num; | ||
106 | for (i = 0; i < n; i++) | ||
107 | @@ -802,14 +816,28 @@ gs_remove_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const | ||
108 | return gs_error_rangecheck; | ||
109 | } | ||
110 | |||
111 | - rlen = len+1; | ||
112 | - buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gp_validate_path"); | ||
113 | - if (buffer == NULL) | ||
114 | - return gs_error_VMerror; | ||
115 | + /* "%pipe%" do not follow the normal rules for path definitions, so we | ||
116 | + don't "reduce" them to avoid unexpected results | ||
117 | + */ | ||
118 | + if (len > 5 && memcmp(path, "%pipe", 5) != 0) { | ||
119 | + buffer = (char *)gs_alloc_bytes(core->memory, len + 1, "gs_remove_control_path_len"); | ||
120 | + if (buffer == NULL) | ||
121 | + return gs_error_VMerror; | ||
122 | + memcpy(buffer, path, len); | ||
123 | + buffer[len] = 0; | ||
124 | + rlen = len; | ||
125 | + } | ||
126 | + else { | ||
127 | + rlen = len+1; | ||
128 | |||
129 | - if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success) | ||
130 | - return gs_error_invalidfileaccess; | ||
131 | - buffer[rlen] = 0; | ||
132 | + buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gs_remove_control_path_len"); | ||
133 | + if (buffer == NULL) | ||
134 | + return gs_error_VMerror; | ||
135 | + | ||
136 | + if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success) | ||
137 | + return gs_error_invalidfileaccess; | ||
138 | + buffer[rlen] = 0; | ||
139 | + } | ||
140 | |||
141 | n = control->num; | ||
142 | for (i = 0; i < n; i++) { | ||
143 | -- | ||
144 | 2.25.1 | ||
145 | |||
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-36664-2.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-36664-2.patch new file mode 100644 index 0000000000..e8c42f1deb --- /dev/null +++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-36664-2.patch | |||
@@ -0,0 +1,60 @@ | |||
1 | From fb342fdb60391073a69147cb71af1ac416a81099 Mon Sep 17 00:00:00 2001 | ||
2 | From: Chris Liddell <chris.liddell@artifex.com> | ||
3 | Date: Wed, 14 Jun 2023 09:08:12 +0100 | ||
4 | Subject: [PATCH] Bug 706778: 706761 revisit | ||
5 | |||
6 | Two problems with the original commit. The first a silly typo inverting the | ||
7 | logic of a test. | ||
8 | |||
9 | The second was forgetting that we actually actually validate two candidate | ||
10 | strings for pipe devices. One with the expected "%pipe%" prefix, the other | ||
11 | using the pipe character prefix: "|". | ||
12 | |||
13 | This addresses both those. | ||
14 | |||
15 | Upstream-Status: Backport [https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=fb342fdb60391073a69147cb71af1ac416a81099] | ||
16 | CVE: CVE-2023-36664 | ||
17 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
18 | --- | ||
19 | base/gpmisc.c | 2 +- | ||
20 | base/gslibctx.c | 4 ++-- | ||
21 | 2 files changed, 3 insertions(+), 3 deletions(-) | ||
22 | |||
23 | diff --git a/base/gpmisc.c b/base/gpmisc.c | ||
24 | index 09ac6b3..01d449f 100644 | ||
25 | --- a/base/gpmisc.c | ||
26 | +++ b/base/gpmisc.c | ||
27 | @@ -1050,7 +1050,7 @@ gp_validate_path_len(const gs_memory_t *mem, | ||
28 | /* "%pipe%" do not follow the normal rules for path definitions, so we | ||
29 | don't "reduce" them to avoid unexpected results | ||
30 | */ | ||
31 | - if (len > 5 && memcmp(path, "%pipe", 5) != 0) { | ||
32 | + if (path[0] == '|' || (len > 5 && memcmp(path, "%pipe", 5) == 0)) { | ||
33 | bufferfull = buffer = (char *)gs_alloc_bytes(mem->thread_safe_memory, len + 1, "gp_validate_path"); | ||
34 | if (buffer == NULL) | ||
35 | return gs_error_VMerror; | ||
36 | diff --git a/base/gslibctx.c b/base/gslibctx.c | ||
37 | index 355c0e3..d8f74a3 100644 | ||
38 | --- a/base/gslibctx.c | ||
39 | +++ b/base/gslibctx.c | ||
40 | @@ -722,7 +722,7 @@ gs_add_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const ch | ||
41 | /* "%pipe%" do not follow the normal rules for path definitions, so we | ||
42 | don't "reduce" them to avoid unexpected results | ||
43 | */ | ||
44 | - if (len > 5 && memcmp(path, "%pipe", 5) != 0) { | ||
45 | + if (path[0] == '|' || (len > 5 && memcmp(path, "%pipe", 5) == 0)) { | ||
46 | buffer = (char *)gs_alloc_bytes(core->memory, len + 1, "gs_add_control_path_len"); | ||
47 | if (buffer == NULL) | ||
48 | return gs_error_VMerror; | ||
49 | @@ -819,7 +819,7 @@ gs_remove_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const | ||
50 | /* "%pipe%" do not follow the normal rules for path definitions, so we | ||
51 | don't "reduce" them to avoid unexpected results | ||
52 | */ | ||
53 | - if (len > 5 && memcmp(path, "%pipe", 5) != 0) { | ||
54 | + if (path[0] == '|' || (len > 5 && memcmp(path, "%pipe", 5) == 0)) { | ||
55 | buffer = (char *)gs_alloc_bytes(core->memory, len + 1, "gs_remove_control_path_len"); | ||
56 | if (buffer == NULL) | ||
57 | return gs_error_VMerror; | ||
58 | -- | ||
59 | 2.25.1 | ||
60 | |||
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-36664-pre1.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-36664-pre1.patch new file mode 100644 index 0000000000..662736bb3d --- /dev/null +++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-36664-pre1.patch | |||
@@ -0,0 +1,62 @@ | |||
1 | From 4ceaf92815302863a8c86fcfcf2347e0118dd3a5 Mon Sep 17 00:00:00 2001 | ||
2 | From: Ray Johnston <ray.johnston@artifex.com> | ||
3 | Date: Tue, 22 Sep 2020 13:10:04 -0700 | ||
4 | Subject: [PATCH] Fix gp_file allocations to use thread_safe_memory. | ||
5 | |||
6 | The gpmisc.c does allocations for gp_file objects and buffers used by | ||
7 | gp_fprintf, as well as gp_validate_path_len. The helgrind run with | ||
8 | -dBGPrint -dNumRenderingThreads=4 and PCL input showed up the gp_fprintf | ||
9 | problem since the clist rendering would call gp_fprintf using the same | ||
10 | allocator (PCL's chunk allocator which is non_gc_memory). The chunk | ||
11 | allocator is intentionally not thread safe (for performance). | ||
12 | |||
13 | Upstream-Status: Backport [https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=4ceaf92815302863a8c86fcfcf2347e0118dd3a5] | ||
14 | CVE: CVE-2023-36664 #Dependency Patch1 | ||
15 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
16 | --- | ||
17 | base/gpmisc.c | 8 ++++---- | ||
18 | 1 file changed, 4 insertions(+), 4 deletions(-) | ||
19 | |||
20 | diff --git a/base/gpmisc.c b/base/gpmisc.c | ||
21 | index 34cd71f..c4fffae 100644 | ||
22 | --- a/base/gpmisc.c | ||
23 | +++ b/base/gpmisc.c | ||
24 | @@ -435,7 +435,7 @@ generic_pwrite(gp_file *f, size_t count, gs_offset_t offset, const void *buf) | ||
25 | |||
26 | gp_file *gp_file_alloc(gs_memory_t *mem, const gp_file_ops_t *prototype, size_t size, const char *cname) | ||
27 | { | ||
28 | - gp_file *file = (gp_file *)gs_alloc_bytes(mem->non_gc_memory, size, cname ? cname : "gp_file"); | ||
29 | + gp_file *file = (gp_file *)gs_alloc_bytes(mem->thread_safe_memory, size, cname ? cname : "gp_file"); | ||
30 | if (file == NULL) | ||
31 | return NULL; | ||
32 | |||
33 | @@ -449,7 +449,7 @@ gp_file *gp_file_alloc(gs_memory_t *mem, const gp_file_ops_t *prototype, size_t | ||
34 | memset(((char *)file)+sizeof(*prototype), | ||
35 | 0, | ||
36 | size - sizeof(*prototype)); | ||
37 | - file->memory = mem->non_gc_memory; | ||
38 | + file->memory = mem->thread_safe_memory; | ||
39 | |||
40 | return file; | ||
41 | } | ||
42 | @@ -1047,7 +1047,7 @@ gp_validate_path_len(const gs_memory_t *mem, | ||
43 | prefix_len = 0; | ||
44 | } | ||
45 | rlen = len+1; | ||
46 | - bufferfull = (char *)gs_alloc_bytes(mem->non_gc_memory, rlen + prefix_len, "gp_validate_path"); | ||
47 | + bufferfull = (char *)gs_alloc_bytes(mem->thread_safe_memory, rlen + prefix_len, "gp_validate_path"); | ||
48 | if (bufferfull == NULL) | ||
49 | return gs_error_VMerror; | ||
50 | |||
51 | @@ -1093,7 +1093,7 @@ gp_validate_path_len(const gs_memory_t *mem, | ||
52 | break; | ||
53 | } | ||
54 | |||
55 | - gs_free_object(mem->non_gc_memory, bufferfull, "gp_validate_path"); | ||
56 | + gs_free_object(mem->thread_safe_memory, bufferfull, "gp_validate_path"); | ||
57 | #ifdef EACCES | ||
58 | if (code == gs_error_invalidfileaccess) | ||
59 | errno = EACCES; | ||
60 | -- | ||
61 | 2.25.1 | ||
62 | |||
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-43115.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-43115.patch new file mode 100644 index 0000000000..3acb8a503c --- /dev/null +++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2023-43115.patch | |||
@@ -0,0 +1,62 @@ | |||
1 | From 8b0f20002536867bd73ff4552408a72597190cbe Mon Sep 17 00:00:00 2001 | ||
2 | From: Ken Sharp <ken.sharp@artifex.com> | ||
3 | Date: Thu, 24 Aug 2023 15:24:35 +0100 | ||
4 | Subject: [PATCH] IJS device - try and secure the IJS server startup | ||
5 | |||
6 | Bug #707051 ""ijs" device can execute arbitrary commands" | ||
7 | |||
8 | The problem is that the 'IJS' device needs to start the IJS server, and | ||
9 | that is indeed an arbitrary command line. There is (apparently) no way | ||
10 | to validate it. Indeed, this is covered quite clearly in the comments | ||
11 | at the start of the source: | ||
12 | |||
13 | * WARNING: The ijs server can be selected on the gs command line | ||
14 | * which is a security risk, since any program can be run. | ||
15 | |||
16 | Previously this used the awful LockSafetyParams hackery, which we | ||
17 | abandoned some time ago because it simply couldn't be made secure (it | ||
18 | was implemented in PostScript and was therefore vulnerable to PostScript | ||
19 | programs). | ||
20 | |||
21 | This commit prevents PostScript programs switching to the IJS device | ||
22 | after SAFER has been activated, and prevents changes to the IjsServer | ||
23 | parameter after SAFER has been activated. | ||
24 | |||
25 | SAFER is activated, unless explicitly disabled, before any user | ||
26 | PostScript is executed which means that the device and the server | ||
27 | invocation can only be configured on the command line. This does at | ||
28 | least provide minimal security against malicious PostScript programs. | ||
29 | |||
30 | Upstream-Status: Backport [https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=e59216049cac290fb437a04c4f41ea46826cfba5] | ||
31 | CVE: CVE-2023-43115 | ||
32 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
33 | --- | ||
34 | devices/gdevijs.c | 5 ++++- | ||
35 | 1 file changed, 4 insertions(+), 1 deletion(-) | ||
36 | |||
37 | diff --git a/devices/gdevijs.c b/devices/gdevijs.c | ||
38 | index 3d337c5..e50d69f 100644 | ||
39 | --- a/devices/gdevijs.c | ||
40 | +++ b/devices/gdevijs.c | ||
41 | @@ -934,6 +934,9 @@ gsijs_finish_copydevice(gx_device *dev, const gx_device *from_dev) | ||
42 | static const char rgb[] = "DeviceRGB"; | ||
43 | gx_device_ijs *ijsdev = (gx_device_ijs *)dev; | ||
44 | |||
45 | + if (ijsdev->memory->gs_lib_ctx->core->path_control_active) | ||
46 | + return_error(gs_error_invalidaccess); | ||
47 | + | ||
48 | code = gx_default_finish_copydevice(dev, from_dev); | ||
49 | if(code < 0) | ||
50 | return code; | ||
51 | @@ -1363,7 +1366,7 @@ gsijs_put_params(gx_device *dev, gs_param_list *plist) | ||
52 | if (code >= 0) | ||
53 | code = gsijs_read_string(plist, "IjsServer", | ||
54 | ijsdev->IjsServer, sizeof(ijsdev->IjsServer), | ||
55 | - dev->LockSafetyParams, is_open); | ||
56 | + ijsdev->memory->gs_lib_ctx->core->path_control_active, is_open); | ||
57 | |||
58 | if (code >= 0) | ||
59 | code = gsijs_read_string_malloc(plist, "DeviceManufacturer", | ||
60 | -- | ||
61 | 2.25.1 | ||
62 | |||
diff --git a/meta/recipes-extended/ghostscript/ghostscript/check-stack-limits-after-function-evalution.patch b/meta/recipes-extended/ghostscript/ghostscript/check-stack-limits-after-function-evalution.patch new file mode 100644 index 0000000000..77eec7d158 --- /dev/null +++ b/meta/recipes-extended/ghostscript/ghostscript/check-stack-limits-after-function-evalution.patch | |||
@@ -0,0 +1,51 @@ | |||
1 | From 7861fcad13c497728189feafb41cd57b5b50ea25 Mon Sep 17 00:00:00 2001 | ||
2 | From: Chris Liddell <chris.liddell@artifex.com> | ||
3 | Date: Fri, 12 Feb 2021 10:34:23 +0000 | ||
4 | Subject: [PATCH] oss-fuzz 30715: Check stack limits after function evaluation. | ||
5 | |||
6 | During function result sampling, after the callout to the Postscript | ||
7 | interpreter, make sure there is enough stack space available before pushing | ||
8 | or popping entries. | ||
9 | |||
10 | In thise case, the Postscript procedure for the "function" is totally invalid | ||
11 | (as a function), and leaves the op stack in an unrecoverable state (as far as | ||
12 | function evaluation is concerned). We end up popping more entries off the | ||
13 | stack than are available. | ||
14 | |||
15 | To cope, add in stack limit checking to throw an appropriate error when this | ||
16 | happens. | ||
17 | CVE: CVE-2021-45944 | ||
18 | Upstream-Status: Backported [https://git.ghostscript.com/?p=ghostpdl.git;a=patch;h=7861fcad13c497728189feafb41cd57b5b50ea25] | ||
19 | Signed-off-by: Minjae Kim <flowergom@gmail.com> | ||
20 | --- | ||
21 | psi/zfsample.c | 14 +++++++++++--- | ||
22 | 1 file changed, 11 insertions(+), 3 deletions(-) | ||
23 | |||
24 | diff --git a/psi/zfsample.c b/psi/zfsample.c | ||
25 | index 290809405..652ae02c6 100644 | ||
26 | --- a/psi/zfsample.c | ||
27 | +++ b/psi/zfsample.c | ||
28 | @@ -551,9 +551,17 @@ sampled_data_continue(i_ctx_t *i_ctx_p) | ||
29 | } else { | ||
30 | if (stack_depth_adjust) { | ||
31 | stack_depth_adjust -= num_out; | ||
32 | - push(O_STACK_PAD - stack_depth_adjust); | ||
33 | - for (i=0;i<O_STACK_PAD - stack_depth_adjust;i++) | ||
34 | - make_null(op - i); | ||
35 | + if ((O_STACK_PAD - stack_depth_adjust) < 0) { | ||
36 | + stack_depth_adjust = -(O_STACK_PAD - stack_depth_adjust); | ||
37 | + check_op(stack_depth_adjust); | ||
38 | + pop(stack_depth_adjust); | ||
39 | + } | ||
40 | + else { | ||
41 | + check_ostack(O_STACK_PAD - stack_depth_adjust); | ||
42 | + push(O_STACK_PAD - stack_depth_adjust); | ||
43 | + for (i=0;i<O_STACK_PAD - stack_depth_adjust;i++) | ||
44 | + make_null(op - i); | ||
45 | + } | ||
46 | } | ||
47 | } | ||
48 | |||
49 | -- | ||
50 | 2.25.1 | ||
51 | |||