diff options
Diffstat (limited to 'gnu/packages')
-rw-r--r-- | gnu/packages/ghostscript.scm | 8 | ||||
-rw-r--r-- | gnu/packages/patches/ghostscript-CVE-2018-16509.patch | 193 | ||||
-rw-r--r-- | gnu/packages/patches/ghostscript-bug-699708.patch | 160 |
3 files changed, 3 insertions, 358 deletions
diff --git a/gnu/packages/ghostscript.scm b/gnu/packages/ghostscript.scm index b46451d94e..d8c0050513 100644 --- a/gnu/packages/ghostscript.scm +++ b/gnu/packages/ghostscript.scm @@ -135,7 +135,7 @@ printing, and psresize, for adjusting page sizes.") (define-public ghostscript (package (name "ghostscript") - (version "9.24") + (version "9.26") (source (origin (method url-fetch) @@ -145,10 +145,8 @@ printing, and psresize, for adjusting page sizes.") "/ghostscript-" version ".tar.xz")) (sha256 (base32 - "1mk922rnml93w2g42yxiyn8xqanc50cm65irrgh0b6lp4kgifjfl")) - (patches (search-patches "ghostscript-CVE-2018-16509.patch" - "ghostscript-bug-699708.patch" - "ghostscript-no-header-creationdate.patch" + "1645f47all5w27bfhiq15vycdm954lmr6agqkrp68ksq6xglgvch")) + (patches (search-patches "ghostscript-no-header-creationdate.patch" "ghostscript-no-header-id.patch" "ghostscript-no-header-uuid.patch")) (modules '((guix build utils))) diff --git a/gnu/packages/patches/ghostscript-CVE-2018-16509.patch b/gnu/packages/patches/ghostscript-CVE-2018-16509.patch deleted file mode 100644 index 50ffa3cb98..0000000000 --- a/gnu/packages/patches/ghostscript-CVE-2018-16509.patch +++ /dev/null @@ -1,193 +0,0 @@ -Ghostscript 9.24 was released with an incomplete fix for CVE-2018-16509: -https://nvd.nist.gov/vuln/detail/CVE-2018-16509 -https://bugs.chromium.org/p/project-zero/issues/detail?id=1640#c19 -https://bugs.ghostscript.com/show_bug.cgi?id=699718 - -The reproducers no longer work after applying these commits: - -https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=5812b1b78fc4d36fdc293b7859de69241140d590 -https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=e914f1da46e33decc534486598dc3eadf69e6efb -https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=3e5d316b72e3965b7968bb1d96baa137cd063ac6 -https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=643b24dbd002fb9c131313253c307cf3951b3d47 - -This patch is a "squashed" version of those. - -diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps -index bba3c8c0e..8fa7c51df 100644 ---- a/Resource/Init/gs_setpd.ps -+++ b/Resource/Init/gs_setpd.ps -@@ -95,27 +95,41 @@ level2dict begin - { % Since setpagedevice doesn't create new device objects, - % we must (carefully) reinstall the old parameters in - % the same device. -- .currentpagedevice pop //null currentdevice //null .trysetparams -+ .currentpagedevice pop //null currentdevice //null -+ { .trysetparams } .internalstopped -+ { -+ //null -+ } if - dup type /booleantype eq - { pop pop } -- { % This should never happen! -+ { - SETPDDEBUG { (Error in .trysetparams!) = pstack flush } if -- cleartomark pop pop pop -+ {cleartomark pop pop pop} .internalstopped pop -+ % if resetting the entire device state failed, at least put back the -+ % security related key -+ currentdevice //null //false mark /.LockSafetyParams -+ currentpagedevice /.LockSafetyParams .knownget not -+ {systemdict /SAFER .knownget not {//false} } if -+ .putdeviceparamsonly - /.installpagedevice cvx /rangecheck signalerror - } - ifelse pop pop - % A careful reading of the Red Book reveals that an erasepage - % should occur, but *not* an initgraphics. - erasepage .beginpage -- } bind def -+ } bind executeonly def - - /.uninstallpagedevice -- { 2 .endpage { .currentnumcopies //false .outputpage } if -+ { -+ {2 .endpage { .currentnumcopies //false .outputpage } if} .internalstopped pop - nulldevice - } bind def - - (%grestorepagedevice) cvn -- { .uninstallpagedevice grestore .installpagedevice -+ { -+ .uninstallpagedevice -+ grestore -+ .installpagedevice - } bind def - - (%grestoreallpagedevice) cvn -diff --git a/psi/zdevice2.c b/psi/zdevice2.c -index 0c7080d57..159a0c0d9 100644 ---- a/psi/zdevice2.c -+++ b/psi/zdevice2.c -@@ -251,8 +251,8 @@ z2currentgstate(i_ctx_t *i_ctx_p) - /* ------ Wrappers for operators that reset the graphics state. ------ */ - - /* Check whether we need to call out to restore the page device. */ --static bool --restore_page_device(const gs_gstate * pgs_old, const gs_gstate * pgs_new) -+static int -+restore_page_device(i_ctx_t *i_ctx_p, const gs_gstate * pgs_old, const gs_gstate * pgs_new) - { - gx_device *dev_old = gs_currentdevice(pgs_old); - gx_device *dev_new; -@@ -260,9 +260,10 @@ restore_page_device(const gs_gstate * pgs_old, const gs_gstate * pgs_new) - gx_device *dev_t2; - bool samepagedevice = obj_eq(dev_old->memory, &gs_int_gstate(pgs_old)->pagedevice, - &gs_int_gstate(pgs_new)->pagedevice); -+ bool LockSafetyParams = dev_old->LockSafetyParams; - - if ((dev_t1 = (*dev_proc(dev_old, get_page_device)) (dev_old)) == 0) -- return false; -+ return 0; - /* If we are going to putdeviceparams in a callout, we need to */ - /* unlock temporarily. The device will be re-locked as needed */ - /* by putdeviceparams from the pgs_old->pagedevice dict state. */ -@@ -271,23 +272,51 @@ restore_page_device(const gs_gstate * pgs_old, const gs_gstate * pgs_new) - dev_new = gs_currentdevice(pgs_new); - if (dev_old != dev_new) { - if ((dev_t2 = (*dev_proc(dev_new, get_page_device)) (dev_new)) == 0) -- return false; -- if (dev_t1 != dev_t2) -- return true; -+ samepagedevice = true; -+ else if (dev_t1 != dev_t2) -+ samepagedevice = false; -+ } -+ -+ if (LockSafetyParams && !samepagedevice) { -+ const int required_ops = 512; -+ const int required_es = 32; -+ -+ /* The %grestorepagedevice must complete: the biggest danger -+ is operand stack overflow. As we use get/putdeviceparams -+ that means pushing all the device params onto the stack, -+ pdfwrite having by far the largest number of parameters -+ at (currently) 212 key/value pairs - thus needing (currently) -+ 424 entries on the op stack. Allowing for working stack -+ space, and safety margin..... -+ */ -+ if (required_ops + ref_stack_count(&o_stack) >= ref_stack_max_count(&o_stack)) { -+ gs_currentdevice(pgs_old)->LockSafetyParams = LockSafetyParams; -+ return_error(gs_error_stackoverflow); -+ } -+ /* We also want enough exec stack space - 32 is an overestimate of -+ what we need to complete the Postscript call out. -+ */ -+ if (required_es + ref_stack_count(&e_stack) >= ref_stack_max_count(&e_stack)) { -+ gs_currentdevice(pgs_old)->LockSafetyParams = LockSafetyParams; -+ return_error(gs_error_execstackoverflow); -+ } - } - /* - * The current implementation of setpagedevice just sets new - * parameters in the same device object, so we have to check - * whether the page device dictionaries are the same. - */ -- return !samepagedevice; -+ return samepagedevice ? 0 : 1; - } - - /* - grestore - */ - static int - z2grestore(i_ctx_t *i_ctx_p) - { -- if (!restore_page_device(igs, gs_gstate_saved(igs))) -+ int code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs)); -+ if (code < 0) return code; -+ -+ if (code == 0) - return gs_grestore(igs); - return push_callout(i_ctx_p, "%grestorepagedevice"); - } -@@ -297,7 +326,9 @@ static int - z2grestoreall(i_ctx_t *i_ctx_p) - { - for (;;) { -- if (!restore_page_device(igs, gs_gstate_saved(igs))) { -+ int code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs)); -+ if (code < 0) return code; -+ if (code == 0) { - bool done = !gs_gstate_saved(gs_gstate_saved(igs)); - - gs_grestore(igs); -@@ -328,11 +359,15 @@ z2restore(i_ctx_t *i_ctx_p) - if (code < 0) return code; - - while (gs_gstate_saved(gs_gstate_saved(igs))) { -- if (restore_page_device(igs, gs_gstate_saved(igs))) -+ code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs)); -+ if (code < 0) return code; -+ if (code > 0) - return push_callout(i_ctx_p, "%restore1pagedevice"); - gs_grestore(igs); - } -- if (restore_page_device(igs, gs_gstate_saved(igs))) -+ code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs)); -+ if (code < 0) return code; -+ if (code > 0) - return push_callout(i_ctx_p, "%restorepagedevice"); - - code = dorestore(i_ctx_p, asave); -@@ -355,9 +390,12 @@ static int - z2setgstate(i_ctx_t *i_ctx_p) - { - os_ptr op = osp; -+ int code; - - check_stype(*op, st_igstate_obj); -- if (!restore_page_device(igs, igstate_ptr(op))) -+ code = restore_page_device(i_ctx_p, igs, igstate_ptr(op)); -+ if (code < 0) return code; -+ if (code == 0) - return zsetgstate(i_ctx_p); - return push_callout(i_ctx_p, "%setgstatepagedevice"); - } diff --git a/gnu/packages/patches/ghostscript-bug-699708.patch b/gnu/packages/patches/ghostscript-bug-699708.patch deleted file mode 100644 index 1567be1c6f..0000000000 --- a/gnu/packages/patches/ghostscript-bug-699708.patch +++ /dev/null @@ -1,160 +0,0 @@ -Additional security fix that missed 9.24. - -Taken from upstream: -http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=fb713b3818b52d8a6cf62c951eba2e1795ff9624 - -From fb713b3818b52d8a6cf62c951eba2e1795ff9624 Mon Sep 17 00:00:00 2001 -From: Chris Liddell <chris.liddell@artifex.com> -Date: Thu, 6 Sep 2018 09:16:22 +0100 -Subject: [PATCH] Bug 699708 (part 1): 'Hide' non-replaceable error handlers - for SAFER - -We already had a 'private' dictionary for non-standard errors: gserrordict. - -This now includes all the default error handlers, the dictionary is made -noaccess and all the prodedures are bound and executeonly. - -When running with -dSAFER, in the event of a Postscript error, instead of -pulling the handler from errordict, we'll pull it from gserrordict - thus -malicious input cannot trigger problems by the use of custom error handlers. - -errordict remains open and writeable, so files such as the Quality Logic tests -that install their own handlers will still 'work', with the exception that the -custom error handlers will not be called. - -This is a 'first pass', 'sledgehammer' approach: a nice addition would to allow -an integrator to specify a list of errors that are not to be replaced (for -example, embedded applications would probably want to ensure that VMerror is -always handled as they intend). ---- - Resource/Init/gs_init.ps | 29 ++++++++++++++++++----------- - psi/interp.c | 30 +++++++++++++++++++++--------- - 2 files changed, 39 insertions(+), 20 deletions(-) - -diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps -index 071c39205..bc8b7951c 100644 ---- a/Resource/Init/gs_init.ps -+++ b/Resource/Init/gs_init.ps -@@ -881,7 +881,7 @@ userdict /.currentresourcefile //null put - { not exch pop exit } { pop } ifelse - } - for exch pop .quit -- } bind def -+ } bind executeonly def - /.errorhandler % <command> <errorname> .errorhandler - - { % Detect an internal 'stopped'. - 1 .instopped { //null eq { pop pop stop } if } if -@@ -926,7 +926,7 @@ userdict /.currentresourcefile //null put - $error /globalmode get $error /.nosetlocal get and .setglobal - $error /.inerror //false put - stop -- } bind def -+ } bind executeonly def - % Define the standard handleerror. We break out the printing procedure - % (.printerror) so that it can be extended for binary output - % if the Level 2 facilities are present. -@@ -976,7 +976,7 @@ userdict /.currentresourcefile //null put - ifelse % newerror - end - flush -- } bind def -+ } bind executeonly def - /.printerror_long % long error printout, - % $error is on the dict stack - { % Push the (anonymous) stack printing procedure. -@@ -1053,14 +1053,14 @@ userdict /.currentresourcefile //null put - { (Current file position is ) print position = } - if - -- } bind def -+ } bind executeonly def - % Define a procedure for clearing the error indication. - /.clearerror - { $error /newerror //false put - $error /errorname //null put - $error /errorinfo //null put - 0 .setoserrno -- } bind def -+ } bind executeonly def - - % Define $error. This must be in local VM. - .currentglobal //false .setglobal -@@ -1086,11 +1086,15 @@ end - /errordict ErrorNames length 3 add dict - .forcedef % errordict is local, systemdict is global - .setglobal % back to global VM --% For greater Adobe compatibility, we put all non-standard errors in a --% separate dictionary, gserrordict. It does not need to be in local VM, --% because PostScript programs do not access it. -+% gserrordict contains all the default error handling methods, but unlike -+% errordict it is noaccess after creation (also it is in global VM). -+% When running 'SAFER', we'll ignore the contents of errordict, which -+% may have been tampered with by the running job, and always use gserrordict -+% gserrordict also contains any non-standard errors, for better compatibility -+% with Adobe. -+% - % NOTE: the name gserrordict is known to the interpreter. --/gserrordict 5 dict def -+/gserrordict ErrorNames length 3 add dict def - % Register an error in errordict. We make this a procedure because we only - % register the Level 1 errors here: the rest are registered by "feature" - % files. However, ErrorNames contains all of the error names regardless of -@@ -1119,8 +1123,11 @@ errordict begin - } bind def - end % errordict - --% Put non-standard errors in gserrordict. --gserrordict /unknownerror errordict /unknownerror get put -+% Put all the default handlers in gserrordict -+gserrordict -+errordict {2 index 3 1 roll put} forall -+noaccess pop -+% remove the non-standard errors from errordict - errordict /unknownerror .undef - % Define a stable private copy of handleerror that we will always use under - % JOBSERVER mode. -diff --git a/psi/interp.c b/psi/interp.c -index c27b70dca..d41a9d3f5 100644 ---- a/psi/interp.c -+++ b/psi/interp.c -@@ -661,16 +661,28 @@ again: - return code; - if (gs_errorname(i_ctx_p, code, &error_name) < 0) - return code; /* out-of-range error code! */ -- /* -- * For greater Adobe compatibility, only the standard PostScript errors -- * are defined in errordict; the rest are in gserrordict. -+ -+ /* If LockFilePermissions is true, we only refer to gserrordict, which -+ * is not accessible to Postcript jobs - */ -- if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 || -- (dict_find(perrordict, &error_name, &epref) <= 0 && -- (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 || -- dict_find(perrordict, &error_name, &epref) <= 0)) -- ) -- return code; /* error name not in errordict??? */ -+ if (i_ctx_p->LockFilePermissions) { -+ if (((dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 || -+ dict_find(perrordict, &error_name, &epref) <= 0)) -+ ) -+ return code; /* error name not in errordict??? */ -+ } -+ else { -+ /* -+ * For greater Adobe compatibility, only the standard PostScript errors -+ * are defined in errordict; the rest are in gserrordict. -+ */ -+ if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 || -+ (dict_find(perrordict, &error_name, &epref) <= 0 && -+ (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 || -+ dict_find(perrordict, &error_name, &epref) <= 0)) -+ ) -+ return code; /* error name not in errordict??? */ -+ } - doref = *epref; - epref = &doref; - /* Push the error object on the operand stack if appropriate. */ --- -2.18.0 - |