diff options
author | Chris Liddell <chris.liddell@artifex.com> | 2022-06-28 13:23:02 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2022-06-30 08:38:45 +0100 |
commit | b609c25f7f881bea4b10c8e1b9b950b635437320 (patch) | |
tree | 509268d9364b536b3d567006397bce30945c07cd /psi | |
parent | 6f4326ab21ae055610c72222da4ab2ac26007589 (diff) | |
download | ghostpdl-b609c25f7f881bea4b10c8e1b9b950b635437320.tar.gz |
oss-fuzz 48305: Use ref counting for subclass child device
The .currentoutputdevice (custom) operator leaves the chance that PS VM still
has a reference to the "child" of a subclassed device. In normal operation,
this isn't a problem, but on an error, that PS reference may persist until
after the unsubclass operation, meaning the "child" is freed while there is
still an active reference to it.
Change the code to use reference counting to ensure that works. This means
considerable fiddling to ensure that, after subclassing, anything sent to the
(now moribund) child device doesn't end up affecting the parent.
Diffstat (limited to 'psi')
-rw-r--r-- | psi/zdevice.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/psi/zdevice.c b/psi/zdevice.c index 99beaff7f..7e9779f7e 100644 --- a/psi/zdevice.c +++ b/psi/zdevice.c @@ -45,7 +45,7 @@ ENUM_PTRS_WITH(psi_device_ref_enum_ptrs, psi_device_ref *devref) } case 0: { - if (devref->device->memory != NULL) { + if (devref->device != NULL && devref->device->memory != NULL) { ENUM_RETURN(gx_device_enum_ptr(devref->device)); } return 0; @@ -54,7 +54,7 @@ ENUM_PTRS_END static RELOC_PTRS_WITH(psi_device_ref_reloc_ptrs, psi_device_ref *devref) - if (devref->device->memory != NULL) { + if (devref->device != NULL && devref->device->memory != NULL) { devref->device = gx_device_reloc_ptr(devref->device, gcst); } RELOC_PTRS_END @@ -71,7 +71,7 @@ psi_device_ref_finalize(const gs_memory_t *cmem, void *vptr) /* pdref->device->memory == NULL indicates either a device prototype or a device allocated on the stack rather than the heap */ - if (pdref->device->memory != NULL) + if (pdref->device != NULL && pdref->device->memory != NULL) rc_decrement(pdref->device, "psi_device_ref_finalize"); pdref->device = NULL; @@ -456,6 +456,7 @@ zmakewordimagedevice(i_ctx_t *i_ctx_p) return_error(gs_error_VMerror); } psdev->device = new_dev; + rc_increment(new_dev); make_tav(op - 4, t_device, imemory_space(iimemory) | a_all, pdevice, psdev); pop(4); } |