123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- 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
|