diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2018-09-07 15:22:29 +0100 |
---|---|---|
committer | Ken Sharp <ken.sharp@artifex.com> | 2018-09-07 15:34:58 +0100 |
commit | 65a9046ded8e9edd5d33bc812a9e94ae29607a1e (patch) | |
tree | 2195c2b596572e0bbe805f979272287b9b284f81 /psi/zcolor1.c | |
parent | 0da9680ca0506fd3cdf70840ad5387d85cab4996 (diff) | |
download | ghostpdl-65a9046ded8e9edd5d33bc812a9e94ae29607a1e.tar.gz |
Bug #699707 "Security review bug - continuation procedures"
As a result of the recent security review, this bug was raised to go
through the PostScript interpreter looking for places where we exit the
'C' level and return control to PostScript. This is done when we need
to evaluate something in the PostScript environment, such as a transfer
function or a tint transform.
Because these functions are written in PostScript we need to run them
in the PostScript environment.
To do this we push the procedure (or at least 'a' procedure) onto the
exec stack and exit with an o_push_estack error. In many cases that's
all we need to do, but sometimes we want to return control back to the
'C' environment and, in some of those cases, we want to store some state
for the C code. We can't use the operand stack (because the PostScript
function will alter that) so we store stuff on the exec stack instead.
When we complete the C level, we should restore the exec stack, so if
we stored any state on it, we should remove it. Sometimes we were not
doing so if there was an error.
Generally this did not cause a problem, because in general on an error
we would stop. However if the error handler had been altered it was
possible we might carry on. 'Sometimes' that would mean we tried to
execute something which wasn't executable, and sometimes it might mean
that we tried to return to the C level, but without the expected
state on the exec stack.
This could lead to memory corruption and crashes.
This commit tries to find everywhere where we might end up leaving
extra items on the exec stack in the case of an error, and either
removes the required number of items from the exec stack or uses
whatever cleanup routine was established for the C code.
Its important to note that, in normal use, none of these could actually
cause a problem. This makes it hard to test. all the cases here I have
tested, though in many cases the only way I could produce an error was
by forcing an error return in the debugger. I suspect some error cases
simply aren't possible but its good practice to check the return codes
anyway, even if its only a theoretical problem.
Diffstat (limited to 'psi/zcolor1.c')
-rw-r--r-- | psi/zcolor1.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/psi/zcolor1.c b/psi/zcolor1.c index 56dcf71d8..1a341ff41 100644 --- a/psi/zcolor1.c +++ b/psi/zcolor1.c @@ -94,6 +94,7 @@ static int zsetcolortransfer(i_ctx_t *i_ctx_p) { os_ptr op = osp; + os_ptr ep = esp; int code; check_proc(op[-3]); @@ -130,8 +131,14 @@ zsetcolortransfer(i_ctx_t *i_ctx_p) (code = zcolor_remap_one(i_ctx_p, &istate->transfer_procs.gray, igs->set_transfer.gray, igs, zcolor_remap_one_finish)) < 0 - ) + ) + { + /* Return the exec stack to the state it was in before we started the setup + * for the transfer function evaluation. + */ + esp = ep; return code; + } return o_push_estack; } |