mirror of
https://git.yoctoproject.org/poky
synced 2026-05-02 18:32:15 +02:00
Artifex Ghostscript 9.25 and earlier allows attackers to bypass a sandbox protection mechanism via vectors involving errorhandler setup. NOTE: this issue exists because of an incomplete fix for CVE-2018-17183. (From OE-Core rev: 6c32ea184941d292cd8f0eb898e6cc90120ada40) Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
106 lines
3.9 KiB
Diff
106 lines
3.9 KiB
Diff
From 34a8c5aa987d4db5234172a62218b168371606b1 Mon Sep 17 00:00:00 2001
|
|
From: Chris Liddell <chris.liddell@artifex.com>
|
|
Date: Tue, 2 Oct 2018 16:02:58 +0100
|
|
Subject: [PATCH 4/5] For hidden operators, pass a name object to error
|
|
handler.
|
|
|
|
In normal operation, Postscript error handlers are passed the object which
|
|
triggered the error: this is invariably an operator object.
|
|
|
|
The issue arises when an error is triggered by an operator which is for internal
|
|
use only, and that operator is then passed to the error handler, meaning it
|
|
becomes visible to the error handler code.
|
|
|
|
By converting to a name object, the error message is still valid, but we no
|
|
longer expose internal use only operators.
|
|
|
|
The change in gs_dps1.ps is related to the above: previously an error in
|
|
scheck would throw an error against .gcheck, but as .gcheck is now a hidden
|
|
operator, it resulted in a name object being passed to the error handler. As
|
|
scheck is a 'real' operator, it's better to use the real operator, rather than
|
|
the name of an internal, hidden one.
|
|
|
|
CVE: CVE-2018-17961
|
|
Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git]
|
|
Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
|
|
---
|
|
Resource/Init/gs_dps1.ps | 2 +-
|
|
psi/interp.c | 33 ++++++++++++++++++++++++---------
|
|
2 files changed, 25 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps
|
|
index 1182f53..ec5db61 100644
|
|
--- a/Resource/Init/gs_dps1.ps
|
|
+++ b/Resource/Init/gs_dps1.ps
|
|
@@ -21,7 +21,7 @@ level2dict begin
|
|
% ------ Virtual memory ------ %
|
|
|
|
/currentshared /.currentglobal load def
|
|
-/scheck /.gcheck load def
|
|
+/scheck {.gcheck} bind odef
|
|
%****** FOLLOWING IS WRONG ******
|
|
/shareddict currentdict /globaldict .knownget not { 20 dict } if def
|
|
|
|
diff --git a/psi/interp.c b/psi/interp.c
|
|
index cd894f9..b70769d 100644
|
|
--- a/psi/interp.c
|
|
+++ b/psi/interp.c
|
|
@@ -678,6 +678,8 @@ again:
|
|
epref = &doref;
|
|
/* Push the error object on the operand stack if appropriate. */
|
|
if (!GS_ERROR_IS_INTERRUPT(code)) {
|
|
+ byte buf[260], *bufptr;
|
|
+ uint rlen;
|
|
/* Replace the error object if within an oparray or .errorexec. */
|
|
osp++;
|
|
if (osp >= ostop) {
|
|
@@ -686,23 +688,36 @@ again:
|
|
}
|
|
*osp = *perror_object;
|
|
errorexec_find(i_ctx_p, osp);
|
|
- /* If using SAFER, hand a name object to the error handler, rather than the executable
|
|
- * object/operator itself.
|
|
- */
|
|
- if (i_ctx_p->LockFilePermissions) {
|
|
+
|
|
+ if (!r_has_type(osp, t_string) && !r_has_type(osp, t_name)) {
|
|
code = obj_cvs(imemory, osp, buf + 2, 256, &rlen, (const byte **)&bufptr);
|
|
if (code < 0) {
|
|
const char *unknownstr = "--unknown--";
|
|
rlen = strlen(unknownstr);
|
|
memcpy(buf, unknownstr, rlen);
|
|
+ bufptr = buf;
|
|
}
|
|
else {
|
|
- buf[0] = buf[1] = buf[rlen + 2] = buf[rlen + 3] = '-';
|
|
- rlen += 4;
|
|
+ ref *tobj;
|
|
+ bufptr[rlen] = '\0';
|
|
+ /* Only pass a name object if the operator doesn't exist in systemdict
|
|
+ * i.e. it's an internal operator we have hidden
|
|
+ */
|
|
+ code = dict_find_string(systemdict, (const char *)bufptr, &tobj);
|
|
+ if (code < 0) {
|
|
+ buf[0] = buf[1] = buf[rlen + 2] = buf[rlen + 3] = '-';
|
|
+ rlen += 4;
|
|
+ bufptr = buf;
|
|
+ }
|
|
+ else {
|
|
+ bufptr = NULL;
|
|
+ }
|
|
+ }
|
|
+ if (bufptr) {
|
|
+ code = name_ref(imemory, buf, rlen, osp, 1);
|
|
+ if (code < 0)
|
|
+ make_null(osp);
|
|
}
|
|
- code = name_ref(imemory, buf, rlen, osp, 1);
|
|
- if (code < 0)
|
|
- make_null(osp);
|
|
}
|
|
}
|
|
goto again;
|
|
--
|
|
2.7.4
|
|
|