161 lines
6.5 KiB
Diff
161 lines
6.5 KiB
Diff
|
Additional security fix that missed 9.24.
|
||
|
|
||
|
Taken from upstream:
|
||
|
http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=fb713b3818b52d8a6cf62c951eba2e1795ff9624
|
||
|
|
||
|
From fb713b3818b52d8a6cf62c951eba2e1795ff9624 Mon Sep 17 00:00:00 2001
|
||
|
From: Chris Liddell <chris.liddell@artifex.com>
|
||
|
Date: Thu, 6 Sep 2018 09:16:22 +0100
|
||
|
Subject: [PATCH] Bug 699708 (part 1): 'Hide' non-replaceable error handlers
|
||
|
for SAFER
|
||
|
|
||
|
We already had a 'private' dictionary for non-standard errors: gserrordict.
|
||
|
|
||
|
This now includes all the default error handlers, the dictionary is made
|
||
|
noaccess and all the prodedures are bound and executeonly.
|
||
|
|
||
|
When running with -dSAFER, in the event of a Postscript error, instead of
|
||
|
pulling the handler from errordict, we'll pull it from gserrordict - thus
|
||
|
malicious input cannot trigger problems by the use of custom error handlers.
|
||
|
|
||
|
errordict remains open and writeable, so files such as the Quality Logic tests
|
||
|
that install their own handlers will still 'work', with the exception that the
|
||
|
custom error handlers will not be called.
|
||
|
|
||
|
This is a 'first pass', 'sledgehammer' approach: a nice addition would to allow
|
||
|
an integrator to specify a list of errors that are not to be replaced (for
|
||
|
example, embedded applications would probably want to ensure that VMerror is
|
||
|
always handled as they intend).
|
||
|
---
|
||
|
Resource/Init/gs_init.ps | 29 ++++++++++++++++++-----------
|
||
|
psi/interp.c | 30 +++++++++++++++++++++---------
|
||
|
2 files changed, 39 insertions(+), 20 deletions(-)
|
||
|
|
||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
|
||
|
index 071c39205..bc8b7951c 100644
|
||
|
--- a/Resource/Init/gs_init.ps
|
||
|
+++ b/Resource/Init/gs_init.ps
|
||
|
@@ -881,7 +881,7 @@ userdict /.currentresourcefile //null put
|
||
|
{ not exch pop exit } { pop } ifelse
|
||
|
}
|
||
|
for exch pop .quit
|
||
|
- } bind def
|
||
|
+ } bind executeonly def
|
||
|
/.errorhandler % <command> <errorname> .errorhandler -
|
||
|
{ % Detect an internal 'stopped'.
|
||
|
1 .instopped { //null eq { pop pop stop } if } if
|
||
|
@@ -926,7 +926,7 @@ userdict /.currentresourcefile //null put
|
||
|
$error /globalmode get $error /.nosetlocal get and .setglobal
|
||
|
$error /.inerror //false put
|
||
|
stop
|
||
|
- } bind def
|
||
|
+ } bind executeonly def
|
||
|
% Define the standard handleerror. We break out the printing procedure
|
||
|
% (.printerror) so that it can be extended for binary output
|
||
|
% if the Level 2 facilities are present.
|
||
|
@@ -976,7 +976,7 @@ userdict /.currentresourcefile //null put
|
||
|
ifelse % newerror
|
||
|
end
|
||
|
flush
|
||
|
- } bind def
|
||
|
+ } bind executeonly def
|
||
|
/.printerror_long % long error printout,
|
||
|
% $error is on the dict stack
|
||
|
{ % Push the (anonymous) stack printing procedure.
|
||
|
@@ -1053,14 +1053,14 @@ userdict /.currentresourcefile //null put
|
||
|
{ (Current file position is ) print position = }
|
||
|
if
|
||
|
|
||
|
- } bind def
|
||
|
+ } bind executeonly def
|
||
|
% Define a procedure for clearing the error indication.
|
||
|
/.clearerror
|
||
|
{ $error /newerror //false put
|
||
|
$error /errorname //null put
|
||
|
$error /errorinfo //null put
|
||
|
0 .setoserrno
|
||
|
- } bind def
|
||
|
+ } bind executeonly def
|
||
|
|
||
|
% Define $error. This must be in local VM.
|
||
|
.currentglobal //false .setglobal
|
||
|
@@ -1086,11 +1086,15 @@ end
|
||
|
/errordict ErrorNames length 3 add dict
|
||
|
.forcedef % errordict is local, systemdict is global
|
||
|
.setglobal % back to global VM
|
||
|
-% For greater Adobe compatibility, we put all non-standard errors in a
|
||
|
-% separate dictionary, gserrordict. It does not need to be in local VM,
|
||
|
-% because PostScript programs do not access it.
|
||
|
+% gserrordict contains all the default error handling methods, but unlike
|
||
|
+% errordict it is noaccess after creation (also it is in global VM).
|
||
|
+% When running 'SAFER', we'll ignore the contents of errordict, which
|
||
|
+% may have been tampered with by the running job, and always use gserrordict
|
||
|
+% gserrordict also contains any non-standard errors, for better compatibility
|
||
|
+% with Adobe.
|
||
|
+%
|
||
|
% NOTE: the name gserrordict is known to the interpreter.
|
||
|
-/gserrordict 5 dict def
|
||
|
+/gserrordict ErrorNames length 3 add dict def
|
||
|
% Register an error in errordict. We make this a procedure because we only
|
||
|
% register the Level 1 errors here: the rest are registered by "feature"
|
||
|
% files. However, ErrorNames contains all of the error names regardless of
|
||
|
@@ -1119,8 +1123,11 @@ errordict begin
|
||
|
} bind def
|
||
|
end % errordict
|
||
|
|
||
|
-% Put non-standard errors in gserrordict.
|
||
|
-gserrordict /unknownerror errordict /unknownerror get put
|
||
|
+% 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
|
||
|
errordict /unknownerror .undef
|
||
|
% Define a stable private copy of handleerror that we will always use under
|
||
|
% JOBSERVER mode.
|
||
|
diff --git a/psi/interp.c b/psi/interp.c
|
||
|
index c27b70dca..d41a9d3f5 100644
|
||
|
--- a/psi/interp.c
|
||
|
+++ b/psi/interp.c
|
||
|
@@ -661,16 +661,28 @@ again:
|
||
|
return code;
|
||
|
if (gs_errorname(i_ctx_p, code, &error_name) < 0)
|
||
|
return code; /* out-of-range error code! */
|
||
|
- /*
|
||
|
- * For greater Adobe compatibility, only the standard PostScript errors
|
||
|
- * are defined in errordict; the rest are in gserrordict.
|
||
|
+
|
||
|
+ /* If LockFilePermissions is true, we only refer to gserrordict, which
|
||
|
+ * is not accessible to Postcript jobs
|
||
|
*/
|
||
|
- 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 (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??? */
|
||
|
+ }
|
||
|
doref = *epref;
|
||
|
epref = &doref;
|
||
|
/* Push the error object on the operand stack if appropriate. */
|
||
|
--
|
||
|
2.18.0
|
||
|
|