| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When we successfully create a temporary file from Postscript, either doing so
when SAFER is not in force, or when SAFER is in force, and creating it in
a write permitted directory, we record the file name so we can later delete
the file, even is SAFER has been engaged, or if the PermitWriting list has
changed to no longer the directory in question.
Previously the recording of the name was done in Postscript, even though the
checking was done in C.
This moves the recording of the names to C, meaning we can remove the Postscript
redefinitions of .tempfile and deletfile, and make the dictionary in question
noaccess.
Also, tidy up the adding of the temporary file directory to the list of
permitted directories, and include the list in all of the categories
(PermitFileWriting, PermitFileReading and PermitFileControl) - it was only
previously adding to writing.
|
|
|
|
|
|
| |
The original code worked for one byte code points, and for the case there the
original character code and Unicode value both had the same number of bytes,
but was totally wrong if the the two were different.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The code in z2grestore (part of the level 2 restore machinery) in
ghostpdl/psi/zdevice2.c sets the device's LockSafetyParams to false, and
according to the comments there relies on putdeviceparams setting
the flag back when the old device is re-instated.
However, if we have corrupted any part of the device's content, then
its possible to exit putdeviceparams, in one place only, without
setting LockSafetyParams. Here we simply add an explicit reset of the
value even in the case of an error setting the new device.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In fact, its nothing to do with .bindnow. That simply modifies the exec
stack in a way which makes the problem exhibit.
setcustomcolor should really check its operands. because it doens't, it
creates a tint transform function which tries to mulitply a number by
(in this case) a name. This throws an error of course.
The problem is that the code to sample the tint transform function
didn't deal properly with the case where the PostScript function throws
an error. In that case it properly exits the code which executes the
function, but it fails to unwind the exec stack.
This leads to use trying to complete the function, using the enumerator,
which has been stored on the exec stack. Because we didn't clean up the
exec stack, what we retrieve isn't an enumerator. This causes us to try
to access invalid memory and can result in a crash.
So, several steps. Firstly have the sampling code properly handle the
error and restore the exec stack. Secondly, have the setcolorspace code
be prepared to accept a NULL returned from the sampling code and treat
that as an error (and also fix a similar exec stack problem in the
setcolorspace code). Finally; have setcustomcolor validate its operands.
|
|
|
|
|
|
|
| |
While most of the invocations of .forceput and related operators were
"protected" by being within "executeonly" procedures, several had crept
in that did not make sure that the operator was hidden in a procedure
that could not be read.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 9e58cc8dd7e9b98620c798c901f800aff2e381ce improved the handling of
/Separation spaces with an Lab alternate space.
However, it also altered the handling of Lab spaces as the base space
for patterns, or the initial space. This caused a small difference in
release testing.
The result was incorrect previously, and after the above commit, but the
commit made it appear worse from a user's perspective. Until we can
get time to properly convert Lab base spaces into a device space, return
the code to its prior state. This does not affect the improvement to
Separation spaces.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It is possible for a specifically malformed Binary Object Sequence to
run out of data to process (and return to refill the buffer) when it
had read *exactly* the maximum number of objects declared in the top
array.
This meant that the 'index' pointing to the next expected array entry
to be filled in actually pointed past the end of the array.
We then called a routine to set the unused entries in the array to null
objects (for GC purposes), using the index. Because it pointed past the
end of the array this led to the count of objects being -1. The code
then counted down the count, until it reached 0, while at the same time
writing null objects past the end of the array.
This commit simply checks the index against the array size and doesn't
attempt to fill it in if its less than that value. Note that the array
index is 0-based, hence < not <=.
|
| |
|
| |
|
|
|
|
| |
Thanks to oss-fuzz for reporting.
|
|
|
|
| |
Thanks to coverity.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Take inspiration from the code to remove unused/dangerous operators
and, when SAFER is true, remove a bunch more non-standard operators
or routines.
In particular remove the .bindnow operator, which should have been
removed previously for Bug #699677 and remove the
.pushpdf14devicefilter for Bug #699654. Only the PDF interpreter
needs to use that, and the device in question only expects to be used
carefully and in the correct sequence. Make sure nobody can meddle with
it.
In addition I removed a number of other operators which are not needed
in normal operation. Some of them, however, are useful so these
(with the exception of .bindnow which is always removed) are only
undefined if SAFER is true.
This allows our QA procedure to continue to use them, which is
particularly important in the case of .makeoperator and .setCPSImode.
At a later date we may choose to move some of these into the regular
undefinition code, ie not dependent on SAFER.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the FAPI code, when dealing a substituted cidfont, we extract the original
character code, and decode that using the ToUnicode CMap, in order to get a
Unicode code point we can then put through the TTF Unicode cmap table - thus
improving the chances of getting a legible result.
It failed to account for the possiblity that we were dealing with a single
character code stored directly, rather than a string of 1 or more codes in a
buffer - derefencing an invalid pointer.
Add code to handle those cases.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem here is that certain PDF functions require the ability to
use some of the non-standard, and dangerous, operators/procedures
from the PostScript interpreter.
If we leave those functions readable then a malicious PostScript program
could instantiate the PDF interpreter, inspect the packedarrray and
copy the otherwise unobtainable operator/function, then use it for
mischief.
By making the PDF functions executeonly its impossible to read the
function contents, which prevents this kind of abuse.
|
|
|
|
|
|
|
|
|
| |
These are non-standard, and never used, so remove them.
Also rejig gsgetdeviceprop, rename to .gsgetdeviceprop and undefine it after
it's used.
For the only other use of gsgetdeviceprop, replace with a special_op call.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The erasepage optimisation (epo) subclass device shouldn't be allowed to be
copied because the subclass private data, child and parent pointers end up
being shared between the original device and the copy.
Add an epo_finish_copydevice which NULLs the three offending pointers, and
then communicates to the caller that copying is not allowed.
This also exposed a separate issue with the stype for subclasses devices.
Devices are, I think, unique in having two stype objects associated with them:
the usual one in the memory manager header, and the other stored in the device
structere directly. In order for the stype to be correct, we have to use the
stype for the incoming device, with the ssize of the original device (ssize
should reflect the size of the memory allocation). We correctly did so with the
stype in the device structure, but then used the prototype device's stype to
patch the memory manager stype - meaning the ssize potentially no longer
matched the allocated memory. This caused problems in the garbager where there
is an implicit assumption that the size of a single object clump (c_alone == 1)
is also the size (+ memory manager overheads) of the single object it contains.
The solution is to use the same stype instance to patch the memory manager
data as we do in the device structure (with the correct ssize).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The SC and CS PDF operators correctly checked the return code from the
underlying setcolor and setcolorspace code, but we had already
set up the exec stack for handling a non-error return.
We have to do this before calling the underlying code, as that also
uses a state machine, and alters the exec stack. We must push our
own execution context first.
Ordinarily this isn't a problem, but if we have a custom error handler
which doesn't stop the interpreter, then we would continue on to try
and use what we'd pushed onto the exec stack, with predictably dire
results.
Here we avoid this by saving the exec stack pointer on entry, and if
an error occurs, restoring back to that point before returning control
to the PostScript interpreter.
A minor point, but we now also reset the space/color on an error as
well, previously it would have been left with the wrong space set.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The nulldevice does not necessarily use the normal setpagedevice machinery,
but can be set using the nulldevice operator. In which case, we don't preserve
the settings from the original device (in the way setpagedevice does).
Since nulldevice does nothing, this is not generally a problem, but in the case
of LockSafetyParams it *is* important when we restore back to the original
device, when LockSafetyParams not being set is "preserved" into the post-
restore configuration.
We have to initialise the value to false because the nulldevice is used during
initialisation (before any other device exists), and *must* be writable for
that.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Prompted by looking at Bug 699654:
There are two variants of the restore operator in Ghostscript: one is Level 1
(restoring VM), the other is Level 2+ (adding page device restoring to the
Level operator).
This was implemented by the Level 2+ version restoring the device in the
graphics state, then calling the Level 1 implementation to handle actually
restoring the VM state.
The problem was that the operand checking, and sanity of the save object was
only done by the Level 1 variant, thus meaning an invalid save object could
leave a (Level 2+) restore partially complete - with the page device part
restored, but not VM, and the page device not configured.
To solve that, this commit splits the operand and sanity checking, and the
core of the restore operation into separate functions, so the relevant
operators can validate the operand *before* taking any further action. That
reduces the chances of an invalid restore leaving the interpreter in an
unknown state.
If an error occurs during the actual VM restore it is essentially fatal, and the
interpreter cannot continue, but as an extra surety for security, in the event
of such an error, we'll explicitly preserve the LockSafetyParams of the device,
rather than rely on the post-restore device configuration (which won't happen
in the event of an error).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Firstly, hide the .setdistillerparams operator, if we try to use this
with a device which doesn't accept distiller params it could cause
problems. The setdistillerparams operator checks the device before
calling .setdistillerparams. This change is needed in *both*
pdf_main.ps and gs_init.ps (see next)
Secondly, fix the code for hiding PDF operators, when DELAYBIND is
true. We can't undefine the operators in pdf_main.ps if DELAYBIND
is true, because the procedures using them won't have been bound yet.
So we duplicate the code for removing the operators in gs_init.ps
and call that during .bindnow, after all the deferred binding has been
completed.
Previously the code for hiding the PDF and PostScript operators had been
left commented out, meaning that if a user chose DELAYBIND (which is
itself a massive security hole) then this minor layer of security
would not have been activated.
|
|
|
|
|
|
|
|
| |
Commit 0b6cd1918e1ec4ffd087400a754a845180a4522b was supposed to make
the .shfill operator unobtainable, but I accidentally left a comment
in the line doing so.
Fix it here, without this the operator can still be exploited.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The specimen file calls aesdecode without specifying the key to be
used, though it does manage to do enough work with the PDF interpreter
routines to get access to aesdecode (which isn't normally available).
This causes us to read uninitialised memory, which can (and often does)
lead to a segmentation fault.
In this commit we set the key to NULL explicitly during intialisation
and then check it before we read it. If its NULL we just return.
It seems bizarre that we don't return error codes, we should probably
look into that at some point, but this prevents the code trying to
read uninitialised memory.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If the PS job replaces the device and leaves that graphics state in place, we
wouldn't cleanup the default device in the normal way, but rely on the garbage
collector.
This works (but isn't ideal), *except* when the job replaces the device with
the null device (using the nulldevice operator) - this means that
.uninstallpagedevice doesn't replace the existing device with the nulldevice
(since it is already installed), the device from the graphics ends up being
freed - and as it is the nulldevice, which we rely on, memory corruption
and a segfault can happen.
We avoid this by checking if the current device is the nulldevice, and if so,
restoring it away, before continuing with the device cleanup.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If a copdevice is triggered when the pdf14 compositor is the device, we make
a copy of the device, then throw an error because, by default we're only allowed
to copy the device prototype - then freeing it calls the finalize, which frees
several pointers shared with the parent.
Make a pdf14 specific finish_copydevice() which NULLs the relevant pointers,
before, possibly, throwing the same error as the default method.
This also highlighted a problem with reopening the X11 devices, where a custom
error handler could be replaced with itself, meaning it also called itself,
and infifite recursion resulted.
Keep a note of if the handler replacement has been done, and don't do it a
second time.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Its possible to pass a t_struct parameter to .shfill which is not a
shading function built by .buildshading. This could then lead to memory
corruption or a segmentation fault by treating the object passed in
as if it were a shading.
Its non-trivial to check the t_struct, because this function can take
7 different kinds of structures as a parameter. Checking these is
possible, of course, but would add a performance penalty.
However, we can note that we never call .shfill without first calling
.buildshading, and we never call .buildshading without immediately
calling .shfill. So we can treat these as an atomic operation. The
.buildshading function takes all its parameters as PostScript objects
and validates them, so that should be safe.
This allows us to 'hide' the .shfill operator preventing the possibility
of passing an invalid parameter.
|
|
|
|
|
|
|
|
|
| |
When handling a Postscript error, we push the object throwing the error onto
the operand stack for the error handling procedure to access - we were not
checking the available stack before doing so, thus causing a crash.
Basically, if we get a stack overflow when already handling an error, we're out
of options, return to the caller with a fatal error.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The original fix missed the initial branch with an explicitly specified
directory.
This also uncovered problems with device profile reference counting, where
if profile creation failed we'd leave a pointer to the original profile
in place - either a dangling pointer, or leaving the ref count wrong.
To solve this, we NULL the relevant profile pointer in the device after
adjusting the reference count.
|
|
|
|
|
|
|
|
|
|
| |
The primary function that implements restore correctly checked its parameter,
but a function that does some preliminary work for the restore (gstate and
device handling) did not check.
So, even though the restore correctly errored out, it left things partially done
and, in particular, the device in partially restored state. Meaning the
LockSafetyParams was not correctly set.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Temp files opened for writing before SAFER is engaged are not subject to the
SAFER restrictions - that is handled by recording in a dictionary, and
checking that as part of the permissions checks.
By adding a custom error handler for invalidaccess, that allowed the filename
to be added to the dictionary (despite the attempted open throwing the error)
thus meaning subsequent accesses were erroneously permitted.
|
| |
|
|
|
|
|
| |
This caused a function call commented as "Can't fail" to fail, and resulted
in memory correuption and a segfault.
|
|
|
|
| |
...when getting a value from a dictionary
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Several places in pl_main_process_options(), we were ignoring return codes -
particularly, cases where a genuine error is possible.
Rather than handle each error case automatically, drop out of the switch,
and catch the error before jumping to the top of the while loop.
For consistency, ignore the error triggered by -dBATCH
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Because the display device isn't based off one of the standard devices
we need to do extra work with it to ensure it behaves well with the
subclassing device code.
Commit 1203adc8bbcb60f0e4145300aac44f1988b7c2de contained some of this
work, but unfortunately it had an oversight, it didn't update the
parent (subclassing) devices when the device parameters changed.
This led to it using the wrong width for the raster, if the media
size changed after initialisation.
|
|
|
|
|
| |
Unrecognized PJL settings resulted in a memory leak of the token
buffer.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
param lists can be configured to handle keys in two ways: persistent keys, or
transient keys. For persistent keys, the param list contains a reference to the
key string, and does no management of the string memory.
Configured for transient key strings, the param list makes a copy of the string
and the string memory is managed along with the parameter list itself.
The two approaches cannot be mixed in the same param list.
The pl_main_process_options() code configures the param list to use transient
key strings (which is the default). But it was then copying the key strings,
before passing them to the param list API, and taking no action to manage
the string memory - causing memory leaks.
Since the param list (as configured) takes a copy of the key string, there's no
call for the calling code to do so, and not doing the local string copy
prevents leaking memory.
|
|
|
|
|
|
|
|
|
|
|
|
| |
In gs_initgraphics(), when we create new color spaces for the graphics state
the color space is created with a reference count of 1, we then call
gs_setcolorspace() which attaches the color space to the gstate and increments
the reference count - we then drop the "local" reference, leaving a
reference count of 2, but only a single reference to the color space (the one
in the graphics state). Meaning the memory leaks.
So, decrement the reference count for the local reference, before dropping the
local reference.
|
|
|
|
|
|
|
|
| |
If we end up using the imagemask method to render a cached glyph, we can drop
out early if the glyph is outside the current clip. Previously, the function
simply returned at that point, leaking memory.
Now it falls through to the cleanup and normal return, no longer leaking.
|
|
|
|
|
|
|
| |
I am using 3 flags -- epo-details, epo-install-only, epo-disable.
Can also call "epo_disable(1)" during a gdb session to turn on/off
during the session.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This optimization only works for devices that have a fillpage
implementation that is "gx_default_fillpage". For other devices the
subclass device will not be installed. If the device transitions to
clist (or any other non-gx_default_fillpage device), we will stop
doing the optimization.
The optimization basically swallows(defers) all fillpages, remembering
the color (which is probably always white, but it will work with any
"pure" color). Then when the first actual marking operation happens,
we do a fill_rectangle operation with the remembered color.
|