From b21b1b802da999d20865a29c9d87f2e352f16ece Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 15 2018 15:21:19 +0000 Subject: import ghostscript-9.07-29.el7_5.2 --- 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 +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 +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 +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 ++ */ + /* 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; + } + + /* 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 +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] - 9.07-28.el7_4.2 -- Raise the default VMThreshold from 1Mb to 8Mb (bug #1479852) +* Mon Sep 17 2018 David Kaspar [Dee'Kej] - 9.07-29.el7_5.2 +- Fix MediaPosition, ManualFeed and MediaType with pxl devices (bug #1629842) + +* Mon Sep 10 2018 David Kaspar [Dee'Kej] - 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] - 9.07-28.el7_4.1 +* Tue Jul 25 2017 David Kaspar [Dee'Kej] - 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] - 9.07-28 - Security fix for CVE-2017-8291 updated to address SIGSEGV