From: Chris Liddell Date: Thu, 23 Aug 2018 14:41:18 +0000 (+0100) Subject: Bug 699664: Ensure the correct is in place before cleanup Bug 699664: Ensure the correct is in place before cleanup 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. http://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=241d91112771a6104de10b3948c3f350d6690c1d --- diff -up ghostscript-9.07/psi/imain.c.cve-2018-16541 ghostscript-9.07/psi/imain.c --- ghostscript-9.07/psi/imain.c.cve-2018-16541 2018-11-29 15:54:54.640496328 +0100 +++ ghostscript-9.07/psi/imain.c 2018-11-29 15:56:00.652563801 +0100 @@ -846,6 +846,16 @@ gs_main_finit(gs_main_instance * minst, i_ctx_p = minst->i_ctx_p; /* interp_reclaim could change it. */ } #ifndef PSI_INCLUDED + if (i_ctx_p->pgs != NULL && i_ctx_p->pgs->device != NULL && + gx_device_is_null(i_ctx_p->pgs->device)) { + /* if the job replaced the device with the nulldevice, we we need to grestore + away that device, so the block below can properly dispense + with the default device. + */ + int code = gs_grestoreall(i_ctx_p->pgs); + if (code < 0) return_error(gs_error_Fatal); + } + if (i_ctx_p->pgs != NULL && i_ctx_p->pgs->device != NULL) { gx_device *pdev = i_ctx_p->pgs->device; const char * dname = pdev->dname;