diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2022-07-01 10:07:57 +0100 |
---|---|---|
committer | Ken Sharp <ken.sharp@artifex.com> | 2022-07-01 10:11:10 +0100 |
commit | 510bd436dec7c52cdf7222d3daa4184392453464 (patch) | |
tree | 49684dbd68cf8772063ffcb918f884779243c4e3 /base/gdevp14.c | |
parent | b609c25f7f881bea4b10c8e1b9b950b635437320 (diff) | |
download | ghostpdl-510bd436dec7c52cdf7222d3daa4184392453464.tar.gz |
Fix Nup subclassing device
Chris found this problem when working on OSS-fuzz #48305, setting the
compile-time subclass device testing caused numerous seg faults on the
cluster.
The basic problem is the 'copy_and_modify_sub' routine which is an
altered version of the graphics library 'param_list_copy' function.
Both of these have a bug; the new param list 'persistent_keys' variable
is set from the original param list, but the actual key we use is not
the key from the original list, it's a char buffer on the heap. This
is (obviously) not persistent and if the original list had persistent
keys then we would not copy it. When the buffer went out of scope the
pointer could be corrupted.
Fix both functions here by insisting that the keys be copied
(persistent = false)
Following that, there is a hacky work-around in the pdf14 device for
preventing new copies of 'kernel' subclass devices being installed
when we push a compositor. The Nup device hadn't been added there.
Add the device to that list, and also add a comment to the function
that installs these devices reminding developers to make similar
changes if they add new devices.
Finally; commit b609c25f7f881bea4b10c8e1b9b950b635437320 changed the
subclassing code to use reference counting, but used rc_decrement on
the 'child' device. That causes seg faults because we rely on the
finalize routine to 'unchain' subclassed devices. The rc_decrement macro
sets the pointer (ie dev->child) to NULL after it has decremented the
reference count and called the finalize routine, which corrupts the
chain.
Use rc_decrement_only which does the deceremnt but does not assign the
pointer to NULL. Add a comment to explain why we are using it.
Diffstat (limited to 'base/gdevp14.c')
-rw-r--r-- | base/gdevp14.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/base/gdevp14.c b/base/gdevp14.c index 3966f9546..60ee9215c 100644 --- a/base/gdevp14.c +++ b/base/gdevp14.c @@ -8891,6 +8891,7 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, new_target->PageHandlerPushed = true; new_target->ObjectHandlerPushed = true; + new_target->NupHandlerPushed = true; /* if the device has separations already defined (by SeparationOrderNames) */ /* we need to copy them (allocating new names) so the colorants are in the */ /* same order as the target device. */ |