A PostScript interpreter and renderer
CentOS Sources
2018-11-26 8812f8a7336a5a46de0f8906f9faaea18c8a0e61
import ghostscript-9.07-31.el7_6.1
4 files added
1 files modified
587 ■■■■■ changed files
SOURCES/ghostscript-cve-2018-15908.patch 204 ●●●●● patch | view | raw | blame | history
SOURCES/ghostscript-cve-2018-15909.patch 91 ●●●●● patch | view | raw | blame | history
SOURCES/ghostscript-cve-2018-16511.patch 29 ●●●●● patch | view | raw | blame | history
SOURCES/ghostscript-remove-as-many-non-standard-operators-as-possible.patch 234 ●●●●● patch | view | raw | blame | history
SPECS/ghostscript.spec 29 ●●●●● patch | view | raw | blame | history
SOURCES/ghostscript-cve-2018-15908.patch
New file
@@ -0,0 +1,204 @@
From: Chris Liddell <chris.liddell@artifex.com>
Date: Tue, 21 Aug 2018 19:17:05 +0000 (+0100)
Subject: Bug 699657: properly apply file permissions to .tempfile
Bug 699657: properly apply file permissions to .tempfile
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=0d3901189f245232f0161addf215d7268c4d05a3
From: Chris Liddell <chris.liddell@artifex.com>
Date: Tue, 21 Aug 2018 19:17:51 +0000 (+0100)
Subject: Bug 699658: Fix handling of pre-SAFER opened files.
Bug 699658: Fix handling of pre-SAFER opened files.
Temp files opened for writing before SAFER is engaged are not subject to the
SAFER restrictions - that is handled by recording in a dictionary, and
checking that as part of the permissions checks.
By adding a custom error handler for invalidaccess, that allowed the filename
to be added to the dictionary (despite the attempted open throwing the error)
thus meaning subsequent accesses were erroneously permitted.
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=a054156d425b4dbdaaa9fda4b5f1182b27598c2b
---
diff -up a/psi/zfile.c.cve-2018-15908 b/psi/zfile.c
--- a/psi/zfile.c.cve-2018-15908    2018-11-14 15:13:31.249625819 +0100
+++ b/psi/zfile.c    2018-11-14 15:14:16.933831779 +0100
@@ -121,7 +121,7 @@ make_invalid_file(i_ctx_t *i_ctx_p, ref
 /* strings of the permitgroup array. */
 static int
 check_file_permissions_reduced(i_ctx_t *i_ctx_p, const char *fname, int len,
-                        const char *permitgroup)
+                        gx_io_device *iodev, const char *permitgroup)
 {
     long i;
     ref *permitlist = NULL;
@@ -131,8 +131,14 @@ check_file_permissions_reduced(i_ctx_t *
     bool use_windows_pathsep = (gs_file_name_check_separator(win_sep2, 1, win_sep2) == 1);
     uint plen = gp_file_name_parents(fname, len);
-    /* Assuming a reduced file name. */
+    /* we're protecting arbitrary file system accesses, not Postscript device accesses.
+     * Although, note that %pipe% is explicitly checked for and disallowed elsewhere
+     */
+    if (iodev && iodev != iodev_default(imemory)) {
+        return 0;
+    }
+    /* Assuming a reduced file name. */
     if (dict_find_string(&(i_ctx_p->userparams), permitgroup, &permitlist) <= 0)
         return 0;       /* if Permissions not found, just allow access */
@@ -187,14 +193,14 @@ check_file_permissions_reduced(i_ctx_t *
 /* strings of the permitgroup array */
 static int
 check_file_permissions(i_ctx_t *i_ctx_p, const char *fname, int len,
-                        const char *permitgroup)
+                        gx_io_device *iodev, const char *permitgroup)
 {
     char fname_reduced[gp_file_name_sizeof];
     uint rlen = sizeof(fname_reduced);
     if (gp_file_name_reduce(fname, len, fname_reduced, &rlen) != gp_combine_success)
         return e_invalidaccess;         /* fail if we couldn't reduce */
-    return check_file_permissions_reduced(i_ctx_p, fname_reduced, rlen, permitgroup);
+    return check_file_permissions_reduced(i_ctx_p, fname_reduced, rlen, iodev, permitgroup);
 }
 /* <name_string> <access_string> file <file> */
@@ -298,7 +304,7 @@ zdeletefile(i_ctx_t *i_ctx_p)
         return code;
     if (pname.iodev == iodev_default(imemory)) {
         if ((code = check_file_permissions(i_ctx_p, pname.fname, pname.len,
-                "PermitFileControl")) < 0 &&
+                pname.iodev, "PermitFileControl")) < 0 &&
                  !file_is_tempfile(i_ctx_p, op->value.bytes, r_size(op))) {
             return code;
         }
@@ -382,7 +388,7 @@ file_continue(i_ctx_t *i_ctx_p)
         } else if (code > len)      /* overran string */
             return_error(gs_error_rangecheck);
         else if (iodev != iodev_default(imemory)
-              || (check_file_permissions_reduced(i_ctx_p, (char *)pscratch->value.bytes, code + devlen, "PermitFileReading")) == 0) {
+              || (check_file_permissions_reduced(i_ctx_p, (char *)pscratch->value.bytes, code + devlen, NULL, "PermitFileReading")) == 0) {
             push(1);
             ref_assign(op, pscratch);
             r_set_size(op, code + devlen);
@@ -432,12 +438,12 @@ zrenamefile(i_ctx_t *i_ctx_p)
                  * and FileWriting permissions to the destination file/path.
                  */
               ((check_file_permissions(i_ctx_p, pname1.fname, pname1.len,
-                                        "PermitFileControl") < 0 &&
+                                        pname1.iodev, "PermitFileControl") < 0 &&
                   !file_is_tempfile(i_ctx_p, op[-1].value.bytes, r_size(op - 1))) ||
               (check_file_permissions(i_ctx_p, pname2.fname, pname2.len,
-                                        "PermitFileControl") < 0 ||
+                                        pname2.iodev, "PermitFileControl") < 0 ||
               check_file_permissions(i_ctx_p, pname2.fname, pname2.len,
-                                        "PermitFileWriting") < 0 )))) {
+                                        pname2.iodev, "PermitFileWriting") < 0 )))) {
             code = gs_note_error(e_invalidfileaccess);
         } else {
             code = (*pname1.iodev->procs.rename_file)(pname1.iodev,
@@ -484,8 +490,11 @@ zstatus(i_ctx_t *i_ctx_p)
                 code = gs_terminate_file_name(&pname, imemory, "status");
                 if (code < 0)
                     return code;
-                code = (*pname.iodev->procs.file_status)(pname.iodev,
+                if ((code = check_file_permissions(i_ctx_p, pname.fname, pname.len,
+                                       pname.iodev, "PermitFileReading")) >= 0) {
+                    code = (*pname.iodev->procs.file_status)(pname.iodev,
                                                        pname.fname, &fstat);
+                }
                 switch (code) {
                     case 0:
                         check_ostack(4);
@@ -694,8 +703,24 @@ ztempfile(i_ctx_t *i_ctx_p)
     }
     if (gp_file_name_is_absolute(pstr, strlen(pstr))) {
-        if (check_file_permissions(i_ctx_p, pstr, strlen(pstr),
-                                   "PermitFileWriting") < 0) {
+        int plen = strlen(pstr);
+        const char *sep = gp_file_name_separator();
+#ifdef DEBUG
+        int seplen = strlen(sep);
+        if (seplen != 1)
+            return_error(gs_error_Fatal);
+#endif
+        /* strip off the file name prefix, leave just the directory name
+         * so we can check if we are allowed to write to it
+         */
+        for ( ; plen >=0; plen--) {
+            if (pstr[plen] == sep[0])
+                break;
+        }
+        memcpy(fname, pstr, plen);
+        fname[plen] = '\0';
+        if (check_file_permissions(i_ctx_p, fname, strlen(fname),
+                                   NULL, "PermitFileWriting") < 0) {
             return_error(e_invalidfileaccess);
         }
     } else if (!prefix_is_simple(pstr)) {
@@ -837,6 +862,7 @@ zopen_file(i_ctx_t *i_ctx_p, const gs_pa
            const char *file_access, stream **ps, gs_memory_t *mem)
 {
     gx_io_device *const iodev = pfn->iodev;
+    int code = 0;
     if (pfn->fname == NULL)     /* just a device */
         return iodev->procs.open_device(iodev, file_access, ps, mem);
@@ -847,7 +873,7 @@ zopen_file(i_ctx_t *i_ctx_p, const gs_pa
             open_file = iodev_os_open_file;
         /* Check OS files to make sure we allow the type of access */
         if (open_file == iodev_os_open_file) {
-            int code = check_file_permissions(i_ctx_p, pfn->fname, pfn->len,
+            code = check_file_permissions(i_ctx_p, pfn->fname, pfn->len, pfn->iodev,
                 file_access[0] == 'r' ? "PermitFileReading" : "PermitFileWriting");
             if (code < 0 && !file_is_tempfile(i_ctx_p,
@@ -894,7 +920,7 @@ check_file_permissions_aux(i_ctx_t *i_ct
     /* fname must be reduced. */
     if (i_ctx_p == NULL)
         return 0;
-    if (check_file_permissions_reduced(i_ctx_p, fname, flen, "PermitFileReading") < 0)
+    if (check_file_permissions_reduced(i_ctx_p, fname, flen, NULL, "PermitFileReading") < 0)
         return_error(e_invalidfileaccess);
     return 0;
 }
diff -up a/Resource/Init/gs_init.ps.cve-2018-15908 b/Resource/Init/gs_init.ps
--- a/Resource/Init/gs_init.ps.cve-2018-15908    2018-11-14 16:34:23.268867657 +0100
+++ b/Resource/Init/gs_init.ps    2018-11-14 16:36:38.765552576 +0100
@@ -2015,6 +2015,19 @@ readonly def
             concatstrings concatstrings .generate_dir_list_templates
         } if
       ]
+      /PermitFileWriting [
+          currentuserparams /PermitFileWriting get aload pop
+          (TMPDIR) getenv not
+          {
+            (TEMP) getenv not
+            {
+              (TMP) getenv not
+              {
+                (/temp) (/tmp)
+              } if
+            } if
+          } if
+      ]
       /LockFilePermissions //true
     >> setuserparams
   }
@@ -2062,7 +2075,9 @@ readonly def
 % the file can be deleted later, even if SAFER is set.
 /.tempfile {
   .tempfile    % filename file
-  //SAFETY /tempfiles get 2 .argindex //true .forceput
+    //SAFETY /safe get not { % only add the filename if we're not yet safe
+    //SAFETY /tempfiles get 2 .argindex //true .forceput
+  } if
 } .bind executeonly odef
 % If we are running in SAFER mode, lock things down
SOURCES/ghostscript-cve-2018-15909.patch
New file
@@ -0,0 +1,91 @@
From: Ken Sharp <ken.sharp@artifex.com>
Date: Thu, 23 Aug 2018 13:12:48 +0000 (+0100)
Subject: Fix Bug 699660 "shading_param incomplete type checking"
Fix Bug 699660 "shading_param incomplete type checking"
Its possible to pass a t_struct parameter to .shfill which is not a
shading function built by .buildshading. This could then lead to memory
corruption or a segmentation fault by treating the object passed in
as if it were a shading.
Its non-trivial to check the t_struct, because this function can take
7 different kinds of structures as a parameter. Checking these is
possible, of course, but would add a performance penalty.
However, we can note that we never call .shfill without first calling
.buildshading, and we never call .buildshading without immediately
calling .shfill. So we can treat these as an atomic operation. The
.buildshading function takes all its parameters as PostScript objects
and validates them, so that should be safe.
This allows us to 'hide' the .shfill operator preventing the possibility
of passing an invalid parameter.
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=0b6cd1918e1ec4ffd087400a754a845180a4522b
From: Ken Sharp <ken.sharp@artifex.com>
Date: Fri, 24 Aug 2018 11:44:26 +0000 (+0100)
Subject: Hide the .shfill operator
Hide the .shfill operator
Commit 0b6cd1918e1ec4ffd087400a754a845180a4522b was supposed to make
the .shfill operator unobtainable, but I accidentally left a comment
in the line doing so.
Fix it here, without this the operator can still be exploited.
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=e01e77a36cbb2e0277bc3a63852244bec41be0f6
---
diff -up a/Resource/Init/gs_init.ps.cve-2018-15909 b/Resource/Init/gs_init.ps
--- a/Resource/Init/gs_init.ps.cve-2018-15909    2018-11-15 12:01:44.102863484 +0100
+++ b/Resource/Init/gs_init.ps    2018-11-15 12:03:16.564421701 +0100
@@ -2136,8 +2136,8 @@ SAFER { .setsafe } if
 /.getiodevice /.getdevparms /.putdevparams /.bbox_transform /.matchmedia /.matchpagesize /.defaultpapersize
 /.oserrno /.setoserrno /.oserrorstring /.getCPSImode
 /.getscanconverter /.setscanconverter /.type1encrypt /.type1decrypt/.languagelevel /.setlanguagelevel /.eqproc /.fillpage /.buildpattern1 /.saslprep
-/.buildshading1 /.buildshadin2 /.buildshading3 /.buildshading4 /.buildshading5 /.buildshading6 /.buildshading7 /.buildshadingpattern
-/.argindex /.bytestring /.namestring /.stringbreak /.stringmatch /.globalvmarray /.globalvmdict /.globalvmpackedarray /.globalvmstring
+/.buildshading1 /.buildshading2 /.buildshading3 /.buildshading4 /.buildshading5 /.buildshading6 /.buildshading7 /.buildshadingpattern
+/.shfill /.argindex /.bytestring /.namestring /.stringbreak /.stringmatch /.globalvmarray /.globalvmdict /.globalvmpackedarray /.globalvmstring
 /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
 /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
 /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath
diff -up a/Resource/Init/gs_ll3.ps.cve-2018-15909 b/Resource/Init/gs_ll3.ps
--- a/Resource/Init/gs_ll3.ps.cve-2018-15909    2018-11-15 12:03:38.878073758 +0100
+++ b/Resource/Init/gs_ll3.ps    2018-11-15 12:04:56.895857191 +0100
@@ -406,6 +406,11 @@ systemdict /.reuseparamdict mark
     /shfill .systemvar /undefined signalerror
   } ifelse
 } bind def
+
+/.buildshading_and_shfill {
+  .buildshading .shfill
+} bind def
+
 systemdict /.reuseparamdict undef
 /.buildpattern2 {    % <template> <matrix> .buildpattern2
@@ -430,7 +435,7 @@ systemdict /.reuseparamdict undef
         % Currently, .shfill requires that the color space
         % in the pattern be the current color space.
         % Disable overprintmode for shfill
-  { dup gsave 0 .setoverprintmode .buildshading .shfill } stopped
+  { dup gsave 0 .setoverprintmode .buildshading_and_shfill } stopped
   grestore {
     /$error .systemvar /errorinfo 2 copy known {
       pop pop
diff -up a/Resource/Init/pdf_draw.ps.cve-2018-15909 b/Resource/Init/pdf_draw.ps
--- a/Resource/Init/pdf_draw.ps.cve-2018-15909    2018-11-15 12:05:34.592269375 +0100
+++ b/Resource/Init/pdf_draw.ps    2018-11-15 12:06:54.143028905 +0100
@@ -1131,7 +1131,7 @@ drawopdict begin
             exch
             pop
           } {
-           .buildshading
+           .buildshading_and_shfill
           } ifelse
           .shfill
         } stopped {
SOURCES/ghostscript-cve-2018-16511.patch
New file
@@ -0,0 +1,29 @@
From: Chris Liddell <chris.liddell@artifex.com>
Date: Tue, 21 Aug 2018 19:36:52 +0000 (+0100)
Subject: Bug 699659: Don't just assume an object is a t_(a)struct
Bug 699659: Don't just assume an object is a t_(a)struct
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=0edd3d6c634a577db261615a9dc2719bca7f6e01
---
diff -up a/psi/ztype.c.cve-2018-16511 b/psi/ztype.c
--- a/psi/ztype.c.cve-2018-16511    2018-11-14 09:52:09.491518742 +0100
+++ b/psi/ztype.c    2018-11-14 10:14:02.238279799 +0100
@@ -76,6 +76,7 @@ ztype(i_ctx_t *i_ctx_p)
         /* Must be either a stack underflow or a t_[a]struct. */
         check_op(2);
         {                       /* Get the type name from the structure. */
+            if ((r_has_type(&op[-1], t_struct) || r_has_type(&op[-1], t_astruct)) && op[-1].value.pstruct != 0x00) {
             const char *sname =
                 gs_struct_type_name_string(gs_object_type(imemory,
                                                           op[-1].value.pstruct));
@@ -84,6 +85,8 @@ ztype(i_ctx_t *i_ctx_p)
             if (code < 0)
                 return code;
+            } else
+                return_error(gs_error_stackunderflow);
         }
         r_set_attrs(op - 1, a_executable);
     } else {
SOURCES/ghostscript-remove-as-many-non-standard-operators-as-possible.patch
New file
@@ -0,0 +1,234 @@
From: Ken Sharp <ken.sharp@artifex.com>
Date: Thu, 11 May 2017 12:09:29 +0000 (+0100)
Subject: Remove as many non-standard operators as possible
Remove as many non-standard operators as possible
Remove all the Display PostScript operators and all the NeXT extensions
Remove all the operators which do not appear to be used in our code
Remove all the operators which are only used in bound procedures defined
at startup and which can therefore subsequently be removed.
The operators to be undefined are stored in arrays in PostScript and
the C support code is untouched. This means that it is relatively
simple for an end user to restore an operator if required.
Operators which are used in our test suite files are listed in the
arrays but commented out.
Operators which are used (by our own code) in a way which requires them
to be present are also listed in the arrays, but commented out.
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=1497d65039885a52b598b137dd8622bd4672f9be
From: Ken Sharp <ken.sharp@artifex.com>
Date: Sat, 17 Jun 2017 10:17:52 +0000 (+0100)
Subject: Make operator hiding work with DELAYBIND
Make operator hiding work with DELAYBIND
Commit 1497d65039885a52b598b137dd8622bd4672f9be undefines as many operators
as possible once startup is completed, in order to prevent potantially
malicious PostScript or PDF files using them.
However, if DELAYBIND (itself a gaping security hole if used) is
specified, this leads to an endless loop. Instead we must undefine the
operators during .bindnow (after the deferred binding has occured).
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=971472c83a345a16dac9f90f91258bb22dd77f22
---
diff -up a/Resource/Init/gs_init.ps.cve-2018-16585 b/Resource/Init/gs_init.ps
--- a/Resource/Init/gs_init.ps.cve-2018-16585    2018-11-14 07:51:00.933247401 +0100
+++ b/Resource/Init/gs_init.ps    2018-11-14 07:51:27.637826808 +0100
@@ -2068,6 +2068,118 @@ readonly def
 % If we are running in SAFER mode, lock things down
 SAFER { .setsafe } if
+/UndefinePostScriptOperators {
+
+%% This list is of Display PostScript operators. We believe that Display PostScript
+%% was never fully implemented and the only known user, GNUStep, is no longer
+%% using it. So lets remove it.
+[
+/condition /currentcontext /detach /.fork /join /.localfork /lock /monitor /notify
+/wait /yield /.currentscreenphase /.setscreenphase /.image2 /eoviewclip /initviewclip
+/viewclip /viewclippath /defineusername
+%% NeXT DPS extensions
+/currentalpha /setalpha /.alphaimage /composite /compositerect /dissolve /sizeimagebox /.sizeimageparams
+]
+{systemdict exch .forceundef} forall
+
+%% This list is of operators which no longer appear to be used, and which we do not believe
+%% to have any real use. For now we will undefine the operstors so they cannot easily be used
+%% but can be easily restored (just delete the name from the list in the array). In future
+%% we may remove the operator and the code implementation entirely.
+[
+/.bitadd /.charboxpath /.currentblackptcomp /.setblackptcomp /.cond /.countexecstack /.execstack /.runandhide /.popdevicefilter
+/.execfile /.filenamesplit /.file_name_parent
+/.setdefaultmatrix /.isprocfilter /.unread /.psstringencode
+/.buildsampledfunction /.isencapfunction /.currentaccuratecurves /.currentcurvejoin /.currentdashadapt /.currentdotlength
+/.currentlimitclamp /.dotorientation /.setaccuratecurves /.setcurvejoin /.setdashadapt /.setdotorientation
+/.setlimitclamp /.currentscreenlevels /.dashpath /.pathbbox /.identeq /.identne /.tokenexec /.forgetsave /.pantonecallback
+
+%% Used by our own test suite files
+%%/.setdotlength % Bug687720.ps
+]
+{systemdict exch .forceundef} forall
+
+%% This list of operators are used internally by various parts of the Ghostscript startup code.
+%% Since each operator is a potential security vulnerability, and any operator listed here
+%% is not required once the initislisation is complete and functions are bound, we undefine
+%% the ones that aren't needed at runtime.
+[
+/.callinstall /.callbeginpage /.callendpage
+/.currentstackprotect /.setstackprotect /.errorexec /.finderrorobject /.installsystemnames /.bosobject /.fontbbox
+/.type1execchar /.type2execchar /.type42execchar /.setweightvector /.getuseciecolor /processcolors /.includecolorspace
+/.execn /.instopped /.stop /.stopped /.setcolorrendering /.setdevicecolorrendering /.buildcolorrendering1 /.builddevicecolorrendering1
+/.TransformPQR_scale_WB0 /.TransformPQR_scale_WB1 /.TransformPQR_scale_WB2 /.currentoverprintmode /.copydevice2
+/.devicename /.doneshowpage /flushpage /.getbitsrect /.getdevice /.getdefaultdevice /.getdeviceparams /.gethardwareparams
+/makewordimagedevice /.outputpage /.putdeviceparams /.setdevice /.currentshowpagecount
+/.setpagedevice /.currentpagedevice /.knownundef /.setmaxlength /.rectappend /.initialize_dsc_parser /.parse_dsc_comments
+/.fillCIDMap /.fillIdentityCIDMap /.buildcmap /.filenamelistseparator /.libfile /.getfilename
+/.file_name_combine /.file_name_is_absolute /.file_name_separator /.file_name_directory_separator /.file_name_current /.filename
+/.peekstring /.writecvp /.subfiledecode /.setupUnicodeDecoder /.jbig2makeglobalctx /.registerfont /.parsecff
+/.getshowoperator /.getnativefonts /.beginform /.endform /.get_form_id /.repeatform /.reusablestream /.rsdparams
+/.buildfunction /.currentfilladjust2 /.setfilladjust2 /.sethpglpathmode /.currenthpglpathmode
+/.currenthalftone /.sethalftone5 /.image1 /.imagemask1 /.image3 /.image4
+/.getiodevice /.getdevparms /.putdevparams /.bbox_transform /.matchmedia /.matchpagesize /.defaultpapersize
+/.oserrno /.setoserrno /.oserrorstring /.getCPSImode
+/.getscanconverter /.setscanconverter /.type1encrypt /.type1decrypt/.languagelevel /.setlanguagelevel /.eqproc /.fillpage /.buildpattern1 /.saslprep
+/.buildshading1 /.buildshadin2 /.buildshading3 /.buildshading4 /.buildshading5 /.buildshading6 /.buildshading7 /.buildshadingpattern
+/.argindex /.bytestring /.namestring /.stringbreak /.stringmatch /.globalvmarray /.globalvmdict /.globalvmpackedarray /.globalvmstring
+/.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
+/.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
+/.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath
+
+% Used by our own test suite files
+%/.fileposition %image-qa.ps
+%/.makeoperator /.setCPSImode % gs_cet.ps
+
+% Either our code uses these in ways which mean they can't be undefined, or they are used directly by
+% test files/utilities, or engineers expressed a desire to keep them visible.
+%
+%/currentdevice /.sort /.buildfont0 /.buildfont1 /.buildfont2 /.buildfont3 /.buildfont4 /.buildfont9 /.buildfont10 /.buildfont11
+%/.buildfotn32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors
+%/currentdevice  /.quit /.setuseciecolor /.needinput /.setoverprintmode /.special_op /.dicttomark /.knownget
+%/.FAPIavailable /.FAPIpassfont /.FAPIrebuildfont /.FAPIBuildGlyph /.FAPIBuildChar /.FAPIBuildGlyph9
+%/.tempfile /.numicc_components /.set_outputintent  /.max /.min /.shfill /.vmreclaim /.getpath /.setglobal
+%/.setdebug /.mementolistnewblocks /getenv
+]
+{systemdict exch .forceundef} forall
+
+//systemdict /UndefinePostScriptOperators .forceundef
+} bind def
+
+/UndefinePDFOperators {
+%% This list of operators are used internally by various parts of the Ghostscript PDF interpreter.
+%% Since each operator is a potential security vulnerability, and any operator listed here
+%% is not required once the initislisation is complete and functions are bound, we undefine
+%% the ones that aren't needed at runtime.
+[
+/.pdfawidthshow /.pdfwidthshow
+/.setfillcolor /.setfillcolorspace /.setstrokecolor /.setstrokecolorspace /.currentrenderingintent /.setrenderingintent
+/.currenttextrenderingmode /.settextspacing /.currenttextspacing /.settextleading /.currenttextleading
+/.settextrise /.currenttextrise /.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling
+/.settextlinematrix /.currenttextlinematrix /.currenttextmatrix /.settextmatrix /.currentblendmode
+/.currentopacityalpha /.currentshapealpha /.currenttextknockout
+/.pushextendedgstate /.popextendedgstate /.begintransparencytextgroup
+/.endtransparencytextgroup /.begintransparencymaskgroup /.begintransparencymaskimage /.endtransparencymask /.image3x
+/.abortpdf14devicefilter /.pdfinkpath /.pdfFormName /.setstrokeconstantalpha
+/.setfillconstantalpha /.setalphaisshape /.currentalphaisshape
+/.settextspacing /.currenttextspacing /.settextleading /.currenttextleading /.settextrise /.currenttextrise
+/.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling
+
+% Used by our own test suite files
+%/.pushpdf14devicefilter    % transparency-example.ps
+%/.poppdf14devicefilter     % transparency-example.ps
+%/.setopacityalpha          % transparency-example.ps
+%/.setshapealpha            % transparency-example.ps
+%/.endtransparencygroup     % transparency-example.ps
+
+% undefining these causes errors/incorrect output
+%/.settextrenderingmode /.setblendmode /.begintransparencygroup /.settextknockout /check_r6_password /.setstrokeoverprint /.setfilloverprint
+%/.currentstrokeoverprint /.currentfilloverprint /.currentfillconstantalpha /.currentstrokeconstantalpha
+]
+{systemdict exch .forceundef} forall
+//systemdict /UndefinePDFOperators .forceundef
+} bind def
+
 % If we delayed binding, make it possible to do it later.
 /.bindnow {
   currentuserparams /IdiomRecognition .knownget {
@@ -2081,6 +2193,8 @@ SAFER { .setsafe } if
   //systemdict /.delaybind {} .forceput    % reclaim the space
   //systemdict /.bindnow .forceundef    % ditto
   put
+%  //systemdict /UndefinePostScriptOperators get exec
+%  //systemdict /UndefinePDFOperators get exec
   //systemdict /.forcecopynew .forceundef    % remove temptation
   //systemdict /.forcedef .forceundef        % ditto
   //systemdict /.forceput .forceundef        % ditto
@@ -2180,6 +2294,13 @@ currentdict /.patterntypes .undef
 currentdict /.shadingtypes .undef
 currentdict /.wheredict .undef
 currentdict /.renderingintentdict .undef
+
+%% If we are using DELAYBIND we have to defer the undefinition
+%% until .bindnow.
+DELAYBIND not {
+  //systemdict /UndefinePostScriptOperators get exec
+  //systemdict /UndefinePDFOperators .forceundef
+} if
 end
 % Clean up VM, and enable GC. Use .vmreclaim to force the GC.
@@ -2197,6 +2318,10 @@ currentdict /superexec .knownget {
   1183615869 internaldict /superexec 3 -1 roll put
   currentdict /superexec .undef
 } if
+
+%% Can't remove this one until the last minute :-)
+systemdict /.undef .undef
+
 WRITESYSTEMDICT not { systemdict readonly pop } if
 (END GC) VMDEBUG
diff -up a/Resource/Init/pdf_main.ps.cve-2018-16585 b/Resource/Init/pdf_main.ps
--- a/Resource/Init/pdf_main.ps.cve-2018-16585    2018-11-14 07:50:45.158495856 +0100
+++ b/Resource/Init/pdf_main.ps    2018-11-14 07:51:16.245006245 +0100
@@ -2347,3 +2347,32 @@ currentdict /PDF2PS_matrix_key undef
 end            % pdfdict
 .setglobal
+
+DELAYBIND not {
+%% This list of operators are used internally by various parts of the Ghostscript PDF interpreter.
+%% Since each operator is a potential security vulnerability, and any operator listed here
+%% is not required once the initislisation is complete and functions are bound, we undefine
+%% the ones that aren't needed at runtime.
+[
+/.pdfawidthshow /.pdfwidthshow
+/.setfillcolor /.setfillcolorspace /.setstrokecolor /.setstrokecolorspace /.currentrenderingintent /.setrenderingintent
+/.currentstrokeoverprint /.setstrokeoverprint /.currentfilloverprint /.setfilloverprint
+/.currenttextrenderingmode /.settextspacing /.currenttextspacing /.settextleading /.currenttextleading
+/.settextrise /.currenttextrise /.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling
+/.setTextLineMatrix /.currentTextLineMatrix /.currentTextMatrix /.setTextMatrix /.currentblendmode
+/.currentopacityalpha /.currentshapealpha /.currenttextknockout
+/.pushextendedgstate /.popextendedgstate /.begintransparencytextgroup
+/.endtransparencytextgroup /.begintransparencymaskgroup /.begintransparencymaskimage /.endtransparencymask /.image3x
+/.abortpdf14devicefilter /.pdfinkpath /.pdfFormName
+
+% Used by our own test suite files
+%/.pushpdf14devicefilter    % transparency-example.ps
+%/.poppdf14devicefilter     % transparency-example.ps
+%/.setopacityalpha          % transparency-example.ps
+%/.setshapealpha            % transparency-example.ps
+%/.endtransparencygroup     % transparency-example.ps
+
+%/.settextrenderingmode /.setblendmode /.begintransparencygroup /.settextknockout /check_r6_password
+]
+{systemdict exch .undef} forall
+} if
SPECS/ghostscript.spec
@@ -5,7 +5,7 @@
Name: ghostscript
Version: %{gs_ver}
Release: 31%{?dist}
Release: 31%{?dist}.1
# Included CMap data is Redistributable, no modification permitted,
# see http://bugzilla.redhat.com/487510
@@ -50,6 +50,7 @@
Patch34: ghostscript-raise-VMThreshold-limit.patch
Patch35: ghostscript-fix-pxl-devices-printing.patch
Patch36: ghostscript-more-than-11-elements-in-array.patch
Patch41: ghostscript-remove-as-many-non-standard-operators-as-possible.patch
# Security patches:
# -----------------
@@ -64,6 +65,9 @@
Patch38: ghostscript-cve-2018-16509.patch
Patch39: ghostscript-cve-2018-15910.patch
Patch40: ghostscript-cve-2018-16542.patch
Patch42: ghostscript-cve-2018-16511.patch
Patch43: ghostscript-cve-2018-15908.patch
Patch44: ghostscript-cve-2018-15909.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
@@ -272,6 +276,19 @@
# CVE-2018-16542 (bug #1621382):
%patch40 -p1
# Remove as many non-standard operators as possible to make the codebase
# closer to upstream for later CVEs:
%patch41 -p1
# CVE-2018-16511 (bug #1621383):
%patch42 -p1
# CVE-2018-15908 (bug #1621159):
%patch43 -p1
# CVE-2018-15909 (bug #1621381):
%patch44 -p1
# Remove pdfopt man pages which were mistakenly left in (bug #963882).
rm man/{de/,}pdfopt.1
@@ -471,6 +488,16 @@
%{_libdir}/libgs.so
%changelog
* Wed Nov 14 2018 Martin Osvald <mosvald@redhat.com> - 9.07-31.el7_6.1
- Remove as many non-standard operators as possible to make the codebase
  closer to upstream for later CVEs
- Resolves: #1621383 - CVE-2018-16511 ghostscript: missing type check in type
  checker (699659)
- Resolves: #1621159 - CVE-2018-15908 ghostscript: .tempfile file permission
  issues (699657)
- Resolves: #1621381 - CVE-2018-15909 ghostscript: shading_param incomplete
  type checking (699660)
* Mon Sep 10 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.07-31
- Added security fixes for:
  - CVE-2018-16509 (bug #1621158)