[arch-commits] Commit in ghostscript/trunk (0006_stack_size_space_fix.patch PKGBUILD)
Andreas Radke
andyrtr at archlinux.org
Sun Sep 9 08:39:24 UTC 2018
Date: Sunday, September 9, 2018 @ 08:39:24
Author: andyrtr
Revision: 334268
upgpkg: ghostscript 9.24-6
yet another security fix - FS#59982
Added:
ghostscript/trunk/0006_stack_size_space_fix.patch
Modified:
ghostscript/trunk/PKGBUILD
---------------------------------+
0006_stack_size_space_fix.patch | 254 ++++++++++++++++++++++++++++++++++++++
PKGBUILD | 10 +
2 files changed, 261 insertions(+), 3 deletions(-)
Added: 0006_stack_size_space_fix.patch
===================================================================
--- 0006_stack_size_space_fix.patch (rev 0)
+++ 0006_stack_size_space_fix.patch 2018-09-09 08:39:24 UTC (rev 334268)
@@ -0,0 +1,254 @@
+From 3e5d316b72e3965b7968bb1d96baa137cd063ac6 Mon Sep 17 00:00:00 2001
+From: Chris Liddell <chris.liddell at artifex.com>
+Date: Wed, 5 Sep 2018 17:14:59 +0100
+Subject: [PATCH] Bug 699718: Ensure stack space is available before gsrestore
+ call out
+
+During a grestore, if the device is going to change, we call out to Postscript
+to restore the device configuration, before returning to restore the graphics
+state internally.
+
+We have to ensure sufficient op stack space is available to complete the
+operation, otherwise the device can end up an undefined state.
+---
+ Resource/Init/gs_setpd.ps | 20 +++++++++++------
+ psi/zdevice2.c | 55 ++++++++++++++++++++++++++++++++++++-----------
+ 2 files changed, 56 insertions(+), 19 deletions(-)
+
+diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps
+index b75c431..8fa7c51 100644
+--- a/Resource/Init/gs_setpd.ps
++++ b/Resource/Init/gs_setpd.ps
+@@ -96,7 +96,7 @@ level2dict begin
+ % we must (carefully) reinstall the old parameters in
+ % the same device.
+ .currentpagedevice pop //null currentdevice //null
+- {.trysetparams} .internalstopped
++ { .trysetparams } .internalstopped
+ {
+ //null
+ } if
+@@ -104,26 +104,32 @@ level2dict begin
+ { pop pop }
+ {
+ 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 pop
+- /.LockSafetyParams .knownget not {//false} if .putdeviceparamsonly
++ 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 0c7080d..5447c8c 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,44 @@ 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) {
++ os_ptr op = osp;
++ const int max_ops = 512;
++
++ /* 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 (max_ops > op - osbot) {
++ if (max_ops >= ref_stack_count(&o_stack))
++ return_error(gs_error_stackoverflow);
++ }
+ }
+ /*
+ * 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 +319,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 +352,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 +383,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");
+ }
+--
+2.9.1
+
+From 643b24dbd002fb9c131313253c307cf3951b3d47 Mon Sep 17 00:00:00 2001
+From: Chris Liddell <chris.liddell at artifex.com>
+Date: Fri, 7 Sep 2018 08:07:12 +0100
+Subject: [PATCH] Bug 699718(2): Improve/augment stack size checking
+
+Improve the rebustness of the previous solution (previously it could trigger an
+error when there *was* stack capacity available).
+
+Remove redundant check: we don't need to check if the *current* stack size is
+sufficient, before checking the maximum permitted stack size.
+
+Also check the exec stack, as execstackoverflow can also cause the
+Postscript call out to fail.
+
+Lastly, in event of failure, put the LockSafetyParams flag back in the existing
+device (this is only necessary because we don't enfore JOBSERVER mode).
+
+Note: the Postscript callout (%grestorepagedevice) never pushes any dictionaries
+on the dict stack - if that changes, we should check that stack, too.
+---
+ psi/zdevice2.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/psi/zdevice2.c b/psi/zdevice2.c
+index 5447c8c..159a0c0 100644
+--- a/psi/zdevice2.c
++++ b/psi/zdevice2.c
+@@ -278,8 +278,8 @@ restore_page_device(i_ctx_t *i_ctx_p, const gs_gstate * pgs_old, const gs_gstate
+ }
+
+ if (LockSafetyParams && !samepagedevice) {
+- os_ptr op = osp;
+- const int max_ops = 512;
++ 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
+@@ -289,9 +289,16 @@ restore_page_device(i_ctx_t *i_ctx_p, const gs_gstate * pgs_old, const gs_gstate
+ 424 entries on the op stack. Allowing for working stack
+ space, and safety margin.....
+ */
+- if (max_ops > op - osbot) {
+- if (max_ops >= ref_stack_count(&o_stack))
+- return_error(gs_error_stackoverflow);
++ 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);
+ }
+ }
+ /*
+--
+2.9.1
+
+
Modified: PKGBUILD
===================================================================
--- PKGBUILD 2018-09-09 08:22:41 UTC (rev 334267)
+++ PKGBUILD 2018-09-09 08:39:24 UTC (rev 334268)
@@ -4,7 +4,7 @@
pkgbase=ghostscript
pkgname=(ghostscript ghostxps ghostpcl)
pkgver=9.24
-pkgrel=5
+pkgrel=6
pkgdesc="An interpreter for the PostScript language"
url="https://www.ghostscript.com/"
arch=('x86_64')
@@ -18,13 +18,15 @@
0002_retain_LockSafetyParams_through_failed_installpagedevice.patch
0003_Fix_SEGV_seen_in_all-devices_test.patch
0004_Add_the_ICCProfilesDir_to_the_PermitReading_list.patch
- 0005_add_wildcards_to_the_permissions_paths.patch)
+ 0005_add_wildcards_to_the_permissions_paths.patch
+ 0006_stack_size_space_fix.patch)
sha512sums=('a0ed7235808ed79ad88ddf0808ef3eb667ffd1b0300ceda78eac3d0ad69d4a963821fa05319ed822db51911210c4fd7d8dbd4d73951e330fbc7b99e4f00a45fa'
'6cfdd351e8e84968c20cf8f15e01a09a215b6132af89ca0e392716638d925a0f750dab3dbcbdf44f200fb9cc419be5dadccffc226c9a405e888f3580f98cf4ea'
'670ccf36927904fc2e918847baf082753d3b4b81fd0ee2347feb6de5a0ab77eb9c00cb640fcb3c7a0f395694112f3921775a6f614bec08e3d4452155b030951e'
'45be77dc890d9d251541d44fe0ad860a7d83d969ce697bbb32cb469d8837417020f1a017ae7aecbb8fbb45647ad9c3e6f92d321c2adfe6c8b3412c580f4058c5'
'e64bcf8e5b5f229ca14463477be21555e66a0f3c76e3c01eb9b4d8cbeebba683b9b33a624ac4617af715c281f93106ae5d8425a29ed35416fbd580242a1a27e0'
- '52088ef6ca47c5ed6f34ccac2b5234bcd6561175ef35de90ede7322a98e617b37036bf8a092733bec11fea211c7e3806b98c4019b1a806f6616387ee48002ef3')
+ '52088ef6ca47c5ed6f34ccac2b5234bcd6561175ef35de90ede7322a98e617b37036bf8a092733bec11fea211c7e3806b98c4019b1a806f6616387ee48002ef3'
+ '4a09455d2e844cf1e8fc91fdfda5e1dd9160dd0a49bad4b1baea186d858bbdaa01980c81022c8f9fb209c329a3668575c47d879cc44db36df6a39bc86eab0928')
prepare() {
cd ghostpdl-${pkgver}
@@ -42,6 +44,8 @@
# FS#59952;FS#59959
patch -Np1 -i ../0004_Add_the_ICCProfilesDir_to_the_PermitReading_list.patch
patch -Np1 -i ../0005_add_wildcards_to_the_permissions_paths.patch
+ # FS#59982
+ patch -Np1 -i ../0006_stack_size_space_fix.patch
}
build() {
More information about the arch-commits
mailing list