[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