123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- From 1f9a91c86bd56acf57826b9b0e020ebe1953e2ae Mon Sep 17 00:00:00 2001
- From: Chris Liddell <chris.liddell@artifex.com>
- Date: Thu, 4 Oct 2018 10:42:13 +0100
- Subject: [PATCH 3/5] Bug 699832: add control over hiding error handlers.
- With a previous commit changing error handling in SAFER so the handler gets
- passed a name object (rather than executable object), it is less critical to
- hide the error handlers.
- This introduces a -dSAFERERRORS option to force only use of the default error
- handlers.
- It also adds a .setsafererrors Postscript call, meaning a caller, without
- -dSAFERERRORS, can create their own default error handlers (in errordict, as
- normal), and then call .setsafererrors meaning their own handlers are always
- called.
- With -dSAFERERRORS or after a call to .setsafererrors, .setsafererrors is
- removed.
- 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_init.ps | 42 +++++++++++++++++++++++++++++------------
- psi/interp.c | 49 ++++++++++++++++++++++++++++--------------------
- 2 files changed, 59 insertions(+), 32 deletions(-)
- diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
- index bec307d..f952f32 100644
- --- a/Resource/Init/gs_init.ps
- +++ b/Resource/Init/gs_init.ps
- @@ -188,6 +188,16 @@ currentdict /DELAYSAFER known { /DELAYSAFER //true def /NOSAFER //true def } if
- currentdict /PARANOIDSAFER known or % PARANOIDSAFER is equivalent
- }
- ifelse def
- +
- +/SAFERERRORS
- +currentdict /NOSAFERERRORS known
- +{
- + //false
- +}
- +{
- + currentdict /SAFERERRORS known
- +} ifelse def
- +
- currentdict /SHORTERRORS known /SHORTERRORS exch def
- currentdict /TTYPAUSE known /TTYPAUSE exch def
- currentdict /WRITESYSTEMDICT known /WRITESYSTEMDICT exch def
- @@ -1123,12 +1133,23 @@ errordict begin
- } bind def
- end % errordict
-
- -% Put all the default handlers in gserrordict
- -gserrordict
- -errordict {2 index 3 1 roll put} forall
- -noaccess pop
- -% remove the non-standard errors from errordict
- +gserrordict /unknownerror errordict /unknownerror get put
- errordict /unknownerror .undef
- +
- +/.SAFERERRORLIST ErrorNames def
- +/.setsafererrors
- +{
- +% Put all the requested handlers in gserrordict
- + gserrordict
- + //.SAFERERRORLIST
- + {dup errordict exch get 2 index 3 1 roll put} forall
- + noaccess pop
- + systemdict /.setsafeerrors .forceundef
- + systemdict /.SAFERERRORLIST .forceundef
- +} bind executeonly odef
- +
- +SAFERERRORS {.setsafererrors} if
- +
- % Define a stable private copy of handleerror that we will always use under
- % JOBSERVER mode.
- /.GShandleerror errordict /handleerror get def
- @@ -1760,18 +1781,15 @@ currentdict /.runlibfile .undef
-
- % Bind all the operators defined as procedures.
- /.bindoperators % binds operators in currentdict
- - { % Temporarily disable the typecheck error.
- - errordict /typecheck 2 copy get
- - errordict /typecheck { pop } put % pop the command
- + {
- currentdict
- { dup type /operatortype eq
- - { % This might be a real operator, so bind might cause a typecheck,
- - % but we've made the error a no-op temporarily.
- - .bind
- + {
- + % This might be a real operator, so bind might cause a typecheck
- + {.bind} .internalstopped pop
- }
- if pop pop
- } forall
- - put
- } def
- DELAYBIND not { .bindoperators } if
-
- diff --git a/psi/interp.c b/psi/interp.c
- index 3dd5f7a..cd894f9 100644
- --- a/psi/interp.c
- +++ b/psi/interp.c
- @@ -662,27 +662,18 @@ again:
- if (gs_errorname(i_ctx_p, code, &error_name) < 0)
- return code; /* out-of-range error code! */
-
- - /* If LockFilePermissions is true, we only refer to gserrordict, which
- - * is not accessible to Postcript jobs
- + /* We refer to gserrordict first, which is not accessible to Postcript jobs
- + * If we're running with SAFERERRORS all the handlers are copied to gserrordict
- + * so we'll always find the default one. If not SAFERERRORS, only gs specific
- + * errors are in gserrordict.
- */
- - if (i_ctx_p->LockFilePermissions) {
- - if (((dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
- - dict_find(perrordict, &error_name, &epref) <= 0))
- - )
- - return code; /* error name not in errordict??? */
- - }
- - else {
- - /*
- - * For greater Adobe compatibility, only the standard PostScript errors
- - * are defined in errordict; the rest are in gserrordict.
- - */
- - if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
- - (dict_find(perrordict, &error_name, &epref) <= 0 &&
- - (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
- - dict_find(perrordict, &error_name, &epref) <= 0))
- - )
- - return code; /* error name not in errordict??? */
- - }
- + if (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
- + (dict_find(perrordict, &error_name, &epref) <= 0 &&
- + (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
- + dict_find(perrordict, &error_name, &epref) <= 0))
- + )
- + return code; /* error name not in errordict??? */
- +
- doref = *epref;
- epref = &doref;
- /* Push the error object on the operand stack if appropriate. */
- @@ -695,6 +686,24 @@ 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) {
- + 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);
- + }
- + else {
- + buf[0] = buf[1] = buf[rlen + 2] = buf[rlen + 3] = '-';
- + rlen += 4;
- + }
- + code = name_ref(imemory, buf, rlen, osp, 1);
- + if (code < 0)
- + make_null(osp);
- + }
- }
- goto again;
- }
- --
- 2.7.4
|