diff options
| author | Vijay Anusuri <vanusuri@mvista.com> | 2023-09-26 10:01:05 +0530 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2023-10-04 05:17:51 -1000 |
| commit | 16c91216f1d061db34eceaa7042e2c27f7a53c62 (patch) | |
| tree | f066de3b5c0ce03a5a84a8474c5ef19b0f3f5fd9 | |
| parent | e62c723b0c065ef5f35f24bd516681b0491b1c49 (diff) | |
| download | poky-16c91216f1d061db34eceaa7042e2c27f7a53c62.tar.gz | |
ghostscript: fix CVE-2023-36664
Artifex Ghostscript through 10.01.2 mishandles permission validation for
pipe devices (with the %pipe% prefix or the | pipe character prefix).
Reference:
https://nvd.nist.gov/vuln/detail/CVE-2023-36664
Upstream commits:
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=4ceaf92815302863a8c86fcfcf2347e0118dd3a5
https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=5e65eeae225c7d02d447de5abaf4a8e6d234fcea
https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=fb342fdb60391073a69147cb71af1ac416a81099
(From OE-Core rev: 13534218ec37706d9decca5b5bd0453e312d72b0)
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
4 files changed, 270 insertions, 0 deletions
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_9.52.bb b/meta/recipes-extended/ghostscript/ghostscript_9.52.bb index 37e9ed8e84..0a2f9f5046 100644 --- a/meta/recipes-extended/ghostscript/ghostscript_9.52.bb +++ b/meta/recipes-extended/ghostscript/ghostscript_9.52.bb | |||
| @@ -41,6 +41,9 @@ SRC_URI_BASE = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/d | |||
| 41 | file://CVE-2021-3781_3.patch \ | 41 | file://CVE-2021-3781_3.patch \ |
| 42 | file://CVE-2023-28879.patch \ | 42 | file://CVE-2023-28879.patch \ |
| 43 | file://0001-Bug-706897-Copy-pcx-buffer-overrun-fix-from-devices-.patch \ | 43 | file://0001-Bug-706897-Copy-pcx-buffer-overrun-fix-from-devices-.patch \ |
| 44 | file://CVE-2023-36664-pre1.patch \ | ||
| 45 | file://CVE-2023-36664-1.patch \ | ||
| 46 | file://CVE-2023-36664-2.patch \ | ||
| 44 | " | 47 | " |
| 45 | 48 | ||
| 46 | SRC_URI = "${SRC_URI_BASE} \ | 49 | SRC_URI = "${SRC_URI_BASE} \ |
