diff --git a/SOURCES/ghostscript-cve-2018-10194.patch b/SOURCES/ghostscript-cve-2018-10194.patch
new file mode 100644
index 0000000..88c6604
--- /dev/null
+++ b/SOURCES/ghostscript-cve-2018-10194.patch
@@ -0,0 +1,43 @@
+From 544b68a3436e72f138e283af26b168ac46dda4c5 Mon Sep 17 00:00:00 2001
+From: Ken Sharp <ken.sharp@artifex.com>
+Date: Wed, 18 Apr 2018 15:46:32 +0100
+Subject: [PATCH] pdfwrite - Guard against trying to output an infinite number
+
+Bug #699255 " Buffer overflow on pprintg1 due to mishandle postscript file data to pdf"
+
+The file uses an enormous parameter to xyxhow, causing an overflow in
+the calculation of text positioning (value > 1e39).
+
+Since this is basically a nonsense value, and PostScript only supports
+real values up to 1e38, this patch follows the same approach as for
+a degenerate CTM, and treats it as 0.
+
+Adobe Acrobat Distiller throws a limitcheck error, so we could do that
+instead if this approach proves to be a problem.
+---
+ base/gdevpdts.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/base/gdevpdts.c b/base/gdevpdts.c
+index f9321a3..fff6c17 100644
+--- a/base/gdevpdts.c
++++ b/base/gdevpdts.c
+@@ -152,9 +152,14 @@ append_text_move(pdf_text_state_t *pts, floatp dw)
+ static int
+ set_text_distance(gs_point *pdist, floatp dx, floatp dy, const gs_matrix *pmat)
+ {
+-    int code = gs_distance_transform_inverse(dx, dy, pmat, pdist);
++    int code;
+     double rounded;
+ 
++    if (dx > 1e38 || dy > 1e38)
++        code = gs_error_undefinedresult;
++    else
++        code = gs_distance_transform_inverse(dx, dy, pmat, pdist);
++
+     if (code == gs_error_undefinedresult) {
+         /* The CTM is degenerate.
+            Can't know the distance in user space.
+-- 
+2.14.3
+
diff --git a/SOURCES/ghostscript-cve-2018-15910.patch b/SOURCES/ghostscript-cve-2018-15910.patch
new file mode 100644
index 0000000..259fe43
--- /dev/null
+++ b/SOURCES/ghostscript-cve-2018-15910.patch
@@ -0,0 +1,47 @@
+From ebcbe0d685911ffc95f3584f6fcbf1f695959757 Mon Sep 17 00:00:00 2001
+From: Chris Liddell <chris.liddell@artifex.com>
+Date: Tue, 21 Aug 2018 16:42:45 +0100
+Subject: [PATCH] Bug 699656: Handle LockDistillerParams not being a boolean
+
+This caused a function call commented as "Can't fail" to fail, and resulted
+in memory correuption and a segfault.
+---
+ base/gdevpdfp.c | 2 +-
+ psi/iparam.c    | 7 ++++---
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/base/gdevpdfp.c b/base/gdevpdfp.c
+index 7e12fe1..d0f0992 100644
+--- a/base/gdevpdfp.c
++++ b/base/gdevpdfp.c
+@@ -320,7 +320,7 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
+      * LockDistillerParams is read again, and reset if necessary, in
+      * psdf_put_params.
+      */
+-    ecode = code = param_read_bool(plist, "LockDistillerParams", &locked);
++    ecode = code = param_read_bool(plist, (param_name = "LockDistillerParams"), &locked);
+     if (ecode < 0)
+         param_signal_error(plist, param_name, ecode);
+ 
+diff --git a/psi/iparam.c b/psi/iparam.c
+index 559b9b8..6f35745 100644
+--- a/psi/iparam.c
++++ b/psi/iparam.c
+@@ -821,10 +821,11 @@ static int
+ ref_param_read_signal_error(gs_param_list * plist, gs_param_name pkey, int code)
+ {
+     iparam_list *const iplist = (iparam_list *) plist;
+-    iparam_loc loc;
++    iparam_loc loc = {0};
+ 
+-    ref_param_read(iplist, pkey, &loc, -1);	/* can't fail */
+-    *loc.presult = code;
++    ref_param_read(iplist, pkey, &loc, -1);
++    if (loc.presult)
++        *loc.presult = code;
+     switch (ref_param_read_get_policy(plist, pkey)) {
+         case gs_param_policy_ignore:
+             return 0;
+-- 
+2.14.4
+
diff --git a/SOURCES/ghostscript-cve-2018-16509.patch b/SOURCES/ghostscript-cve-2018-16509.patch
new file mode 100644
index 0000000..d39a744
--- /dev/null
+++ b/SOURCES/ghostscript-cve-2018-16509.patch
@@ -0,0 +1,235 @@
+From 26d93b9a3f2a47ece821defe12e9059b4a7a3bf2 Mon Sep 17 00:00:00 2001
+From: Chris Liddell <chris.liddell@artifex.com>
+Date: Fri, 24 Aug 2018 09:26:04 +0100
+Subject: [PATCH] Improve restore robustness
+
+Prompted by looking at Bug 699654:
+
+There are two variants of the restore operator in Ghostscript: one is Level 1
+(restoring VM), the other is Level 2+ (adding page device restoring to the
+Level operator).
+
+This was implemented by the Level 2+ version restoring the device in the
+graphics state, then calling the Level 1 implementation to handle actually
+restoring the VM state.
+
+The problem was that the operand checking, and sanity of the save object was
+only done by the Level 1 variant, thus meaning an invalid save object could
+leave a (Level 2+) restore partially complete - with the page device part
+restored, but not VM, and the page device not configured.
+
+To solve that, this commit splits the operand and sanity checking, and the
+core of the restore operation into separate functions, so the relevant
+operators can validate the operand *before* taking any further action. That
+reduces the chances of an invalid restore leaving the interpreter in an
+unknown state.
+
+If an error occurs during the actual VM restore it is essentially fatal, and the
+interpreter cannot continue, but as an extra surety for security, in the event
+of such an error, we'll explicitly preserve the LockSafetyParams of the device,
+rather than rely on the post-restore device configuration (which won't happen
+in the event of an error).
+---
+ psi/int.mak    |  4 ++--
+ psi/isave.h    |  6 ++++++
+ psi/zdevice2.c | 32 ++++++++++++++++++++++++++++++--
+ psi/zvmem.c    | 56 +++++++++++++++++++++++++++++++++++++++++++++++---------
+ 4 files changed, 85 insertions(+), 13 deletions(-)
+
+diff --git a/psi/int.mak b/psi/int.mak
+index fbf191d..4d0f296 100644
+--- a/psi/int.mak
++++ b/psi/int.mak
+@@ -1047,8 +1047,8 @@ $(PSD)pagedev.dev : $(INT_MAK) $(ECHOGS_XE) $(pagedev_)
+ 
+ $(PSOBJ)zdevice2.$(OBJ) : $(PSSRC)zdevice2.c $(OP) $(math__h) $(memory__h)\
+  $(dstack_h) $(estack_h)\
+- $(idict_h) $(idparam_h) $(igstate_h) $(iname_h) $(iutil_h) $(store_h)\
+- $(gxdevice_h) $(gsstate_h)
++ $(idict_h) $(idparam_h) $(igstate_h) $(iname_h) $(isave) $(iutil_h) \
++ $(store_h) $(gxdevice_h) $(gsstate_h)
+ 	$(PSCC) $(PSO_)zdevice2.$(OBJ) $(C_) $(PSSRC)zdevice2.c
+ 
+ $(PSOBJ)zmedia2.$(OBJ) : $(PSSRC)zmedia2.c $(OP) $(math__h) $(memory__h)\
+diff --git a/psi/isave.h b/psi/isave.h
+index f8a6f32..0914de1 100644
+--- a/psi/isave.h
++++ b/psi/isave.h
+@@ -122,4 +122,10 @@ int  font_restore(const alloc_save_t * save);
+    express purpose of getting the library context. */
+ gs_memory_t *gs_save_any_memory(const alloc_save_t *save);
+ 
++int
++restore_check_save(i_ctx_t *i_ctx_p, alloc_save_t **asave);
++
++int
++dorestore(i_ctx_t *i_ctx_p, alloc_save_t *asave);
++
+ #endif /* isave_INCLUDED */
+diff --git a/psi/zdevice2.c b/psi/zdevice2.c
+index f391da1..2ed2a3b 100644
+--- a/psi/zdevice2.c
++++ b/psi/zdevice2.c
+@@ -26,6 +26,7 @@
+ #include "igstate.h"
+ #include "iname.h"
+ #include "iutil.h"
++#include "isave.h"
+ #include "store.h"
+ #include "gxdevice.h"
+ #include "gsstate.h"
+@@ -306,11 +307,25 @@ z2grestoreall(i_ctx_t *i_ctx_p)
+     }
+     return 0;
+ }
+-
++/* This is the Level 2+ variant of restore - which adds restoring
++   of the page device to the Level 1 variant in zvmem.c.
++   Previous this restored the device state before calling zrestore.c
++   which validated operands etc, meaning a restore could error out
++   partially complete.
++   The operand checking, and actual VM restore are now in two functions
++   so they can called separately thus, here, we can do as much
++   checking as possible, before embarking on actual changes
++ */
+ /* <save> restore - */
+ static int
+ z2restore(i_ctx_t *i_ctx_p)
+ {
++    alloc_save_t *asave;
++    bool saveLockSafety = gs_currentdevice_inline(igs)->LockSafetyParams;
++    int code = restore_check_save(i_ctx_p, &asave);
++
++    if (code < 0) return code;
++
+     while (gs_state_saved(gs_state_saved(igs))) {
+         if (restore_page_device(igs, gs_state_saved(igs)))
+             return push_callout(i_ctx_p, "%restore1pagedevice");
+@@ -318,7 +333,20 @@ z2restore(i_ctx_t *i_ctx_p)
+     }
+     if (restore_page_device(igs, gs_state_saved(igs)))
+         return push_callout(i_ctx_p, "%restorepagedevice");
+-    return zrestore(i_ctx_p);
++
++    code = dorestore(i_ctx_p, asave);
++
++    if (code < 0) {
++        /* An error here is basically fatal, but....
++           restore_page_device() has to set LockSafetyParams false so it can
++           configure the restored device correctly - in normal operation, that
++           gets reset by that configuration. If we hit an error, though, that
++           may not happen -  at least ensure we keep the setting through the
++           error.
++         */
++        gs_currentdevice_inline(igs)->LockSafetyParams = saveLockSafety;
++    }
++    return code;
+ }
+ 
+ /* <gstate> setgstate - */
+diff --git a/psi/zvmem.c b/psi/zvmem.c
+index 4ad8f9a..d8de39d 100644
+--- a/psi/zvmem.c
++++ b/psi/zvmem.c
+@@ -104,19 +104,18 @@ zsave(i_ctx_t *i_ctx_p)
+ static int restore_check_operand(os_ptr, alloc_save_t **, gs_dual_memory_t *);
+ static int restore_check_stack(const i_ctx_t *i_ctx_p, const ref_stack_t *, const alloc_save_t *, bool);
+ static void restore_fix_stack(i_ctx_t *i_ctx_p, ref_stack_t *, const alloc_save_t *, bool);
++
++/* Do as many up front checks of the save object as we reasonably can */
+ int
+-zrestore(i_ctx_t *i_ctx_p)
++restore_check_save(i_ctx_t *i_ctx_p, alloc_save_t **asave)
+ {
+     os_ptr op = osp;
+-    alloc_save_t *asave;
+-    bool last;
+-    vm_save_t *vmsave;
+-    int code = restore_check_operand(op, &asave, idmemory);
++    int code = restore_check_operand(op, asave, idmemory);
+ 
+     if (code < 0)
+         return code;
+     if_debug2m('u', imemory, "[u]vmrestore 0x%lx, id = %lu\n",
+-               (ulong) alloc_save_client_data(asave),
++               (ulong) alloc_save_client_data(*asave),
+                (ulong) op->value.saveid);
+     if (I_VALIDATE_BEFORE_RESTORE)
+         ivalidate_clean_spaces(i_ctx_p);
+@@ -125,14 +124,37 @@ zrestore(i_ctx_t *i_ctx_p)
+     {
+         int code;
+ 
+-        if ((code = restore_check_stack(i_ctx_p, &o_stack, asave, false)) < 0 ||
+-            (code = restore_check_stack(i_ctx_p, &e_stack, asave, true)) < 0 ||
+-            (code = restore_check_stack(i_ctx_p, &d_stack, asave, false)) < 0
++        if ((code = restore_check_stack(i_ctx_p, &o_stack, *asave, false)) < 0 ||
++            (code = restore_check_stack(i_ctx_p, &e_stack, *asave, true)) < 0 ||
++            (code = restore_check_stack(i_ctx_p, &d_stack, *asave, false)) < 0
+             ) {
+             osp++;
+             return code;
+         }
+     }
++    osp++;
++    return 0;
++}
++
++/* the semantics of restore differ slightly between Level 1 and
++   Level 2 and later - the latter includes restoring the device
++   state (whilst Level 1 didn't have "page devices" as such).
++   Hence we have two restore operators - one here (Level 1)
++   and one in zdevice2.c (Level 2+). For that reason, the
++   operand checking and guts of the restore operation are
++   separated so both implementations can use them to best
++   effect.
++ */
++int
++dorestore(i_ctx_t *i_ctx_p, alloc_save_t *asave)
++{
++    os_ptr op = osp;
++    bool last;
++    vm_save_t *vmsave;
++    int code;
++
++    osp--;
++
+     /* Reset l_new in all stack entries if the new save level is zero. */
+     /* Also do some special fixing on the e-stack. */
+     restore_fix_stack(i_ctx_p, &o_stack, asave, false);
+@@ -175,9 +197,24 @@ zrestore(i_ctx_t *i_ctx_p)
+     /* cause an 'invalidaccess' in setuserparams. Temporarily set     */
+     /* LockFilePermissions false until the gs_lev2.ps can do a        */
+     /* setuserparams from the restored userparam dictionary.          */
++    /* NOTE: This is safe to do here, since the restore has           */
++    /* successfully completed - this should never come before any     */
++    /* operation that can trigger an error                            */
+     i_ctx_p->LockFilePermissions = false;
+     return 0;
+ }
++
++int
++zrestore(i_ctx_t *i_ctx_p)
++{
++    alloc_save_t *asave;
++    int code = restore_check_save(i_ctx_p, &asave);
++    if (code < 0)
++        return code;
++
++    return dorestore(i_ctx_p, asave);
++}
++
+ /* Check the operand of a restore. */
+ static int
+ restore_check_operand(os_ptr op, alloc_save_t ** pasave,
+@@ -198,6 +235,7 @@ restore_check_operand(os_ptr op, alloc_save_t ** pasave,
+     *pasave = asave;
+     return 0;
+ }
++
+ /* Check a stack to make sure all its elements are older than a save. */
+ static int
+ restore_check_stack(const i_ctx_t *i_ctx_p, const ref_stack_t * pstack,
+-- 
+2.14.4
+
diff --git a/SOURCES/ghostscript-cve-2018-16542.patch b/SOURCES/ghostscript-cve-2018-16542.patch
new file mode 100644
index 0000000..605ff0a
--- /dev/null
+++ b/SOURCES/ghostscript-cve-2018-16542.patch
@@ -0,0 +1,36 @@
+From b661fd3bf2a7a8ba375131527551bd2834ad1abf Mon Sep 17 00:00:00 2001
+From: Chris Liddell <chris.liddell@artifex.com>
+Date: Thu, 23 Aug 2018 12:20:56 +0100
+Subject: [PATCH] Bug 699668: handle stack overflow during error handling
+
+When handling a Postscript error, we push the object throwing the error onto
+the operand stack for the error handling procedure to access - we were not
+checking the available stack before doing so, thus causing a crash.
+
+Basically, if we get a stack overflow when already handling an error, we're out
+of options, return to the caller with a fatal error.
+---
+ psi/interp.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/psi/interp.c b/psi/interp.c
+index 3e3aaaa..1ed7074 100644
+--- a/psi/interp.c
++++ b/psi/interp.c
+@@ -665,7 +665,12 @@ again:
+     /* Push the error object on the operand stack if appropriate. */
+     if (!ERROR_IS_INTERRUPT(code)) {
+         /* Replace the error object if within an oparray or .errorexec. */
+-        *++osp = *perror_object;
++        osp++;
++        if (osp >= ostop) {
++            *pexit_code = gs_error_Fatal;
++            return_error(gs_error_Fatal);
++        }
++        *osp = *perror_object;
+         errorexec_find(i_ctx_p, osp);
+     }
+     goto again;
+-- 
+2.14.4
+
diff --git a/SPECS/ghostscript.spec b/SPECS/ghostscript.spec
index cf7bb87..fac7b34 100644
--- a/SPECS/ghostscript.spec
+++ b/SPECS/ghostscript.spec
@@ -5,7 +5,7 @@ Summary: A PostScript interpreter and renderer
 Name: ghostscript
 Version: %{gs_ver}
 
-Release: 28%{?dist}.2
+Release: 29%{?dist}.2
 
 # Included CMap data is Redistributable, no modification permitted,
 # see http://bugzilla.redhat.com/487510
@@ -58,6 +58,10 @@ Patch26: ghostscript-cve-2016-7979.patch
 Patch27: ghostscript-cve-2016-8602.patch
 Patch31: ghostscript-cve-2017-7207.patch
 Patch32: ghostscript-cve-2017-8291.patch
+Patch37: ghostscript-cve-2018-10194.patch
+Patch38: ghostscript-cve-2018-16509.patch
+Patch39: ghostscript-cve-2018-15910.patch
+Patch40: ghostscript-cve-2018-16542.patch
 
 # Upstream is not versioning the SONAME correctly, thus the rpmbuild is unable
 # to recognize we need a newer version of lcms2. This 'hackish' workaround
@@ -248,6 +252,18 @@ rm -rf expat freetype icclib jasper jpeg lcms lcms2 libpng openjpeg zlib cups/li
 # Raise the default VMThreshold from 1Mb to 8Mb (bug #1479852):
 %patch34 -p1
 
+# CVE-2018-10194 (bug #1629842):
+%patch37 -p1
+
+# CVE-2018-16509 (bug #1621158):
+%patch38 -p1
+
+# CVE-2018-15910 (bug #1621160):
+%patch39 -p1
+
+# CVE-2018-16542 (bug #1621382):
+%patch40 -p1
+
 # Remove pdfopt man pages which were mistakenly left in (bug #963882).
 rm man/{de/,}pdfopt.1
 
@@ -447,11 +463,18 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/libgs.so
 
 %changelog
-* Tue Aug 22 2017 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.07-28.el7_4.2
-- Raise the default VMThreshold from 1Mb to 8Mb (bug #1479852)
+* Mon Sep 17 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.07-29.el7_5.2
+- Fix MediaPosition, ManualFeed and MediaType with pxl devices (bug #1629842)
+
+* Mon Sep 10 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.07-29.el7_5.1
+- Added security fixes for:
+  - CVE-2018-16509 (bug #1621156)
+  - CVE-2018-15910 (bug #1621157)
+  - CVE-2018-16542 (bug #1621380)
 
-* Tue Jul 25 2017 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.07-28.el7_4.1
+* Tue Jul 25 2017 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.07-29
 - Fix rare Segmentation fault when converting PDF to PNG (bug #1473337)
+- Raise the default VMThreshold from 1Mb to 8Mb (bug #1479852)
 
 * Thu May 11 2017 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.07-28
 - Security fix for CVE-2017-8291 updated to address SIGSEGV