diff options
author | Hongxu Jia <hongxu.jia@windriver.com> | 2018-11-05 16:03:35 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2018-11-06 11:54:30 +0000 |
commit | 6c32ea184941d292cd8f0eb898e6cc90120ada40 (patch) | |
tree | 65cb0c1bdfba62ecbbab1a93d1d8509a90278c50 /meta/recipes-extended/ghostscript/files/0004-For-hidden-operators-pass-a-name-object-to-error-han.patch | |
parent | bd8d2c25f595e30a3fdcad8a2409913bb8af7c5c (diff) | |
download | openembedded-core-contrib-6c32ea184941d292cd8f0eb898e6cc90120ada40.tar.gz |
ghostscript: fix CVE-2018-17961
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.
Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-extended/ghostscript/files/0004-For-hidden-operators-pass-a-name-object-to-error-han.patch')
-rw-r--r-- | meta/recipes-extended/ghostscript/files/0004-For-hidden-operators-pass-a-name-object-to-error-han.patch | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/meta/recipes-extended/ghostscript/files/0004-For-hidden-operators-pass-a-name-object-to-error-han.patch b/meta/recipes-extended/ghostscript/files/0004-For-hidden-operators-pass-a-name-object-to-error-han.patch new file mode 100644 index 0000000000..6c715ad43b --- /dev/null +++ b/meta/recipes-extended/ghostscript/files/0004-For-hidden-operators-pass-a-name-object-to-error-han.patch @@ -0,0 +1,105 @@ +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 + |