Blob Blame History Raw
From: Ken Sharp <ken.sharp@artifex.com>
Date: Wed, 14 Nov 2018 09:25:13 +0000 (+0000)
Subject: Bug #700169 - unchecked type

Bug #700169 - unchecked type

Bug #700169 "Type confusion in setcolorspace"

In seticc() we extract "Name" from a dictionary, if it succeeds we then
use it as a string, without checking the type to see if it is in fact
a string.

Add a check on the type, and add a couple to check that 'N' is an integer
in a few places too.

https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=67d760ab775dae4efe803b5944b0439aa3c0b04a

From: Ken Sharp <ken.sharp@artifex.com>
Date: Wed, 14 Nov 2018 09:31:10 +0000 (+0000)
Subject: PS interpreter - add some type checking

PS interpreter - add some type checking

These were 'probably' safe anyway, since they mostly treat the objects
as integers without checking, which at least can't result in a crash.

Nevertheless, we ought to check.

The return from comparedictkeys could be wrong if one of the keys had
a value which was not an array, it could incorrectly decide the two
were in fact the same.

https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=548bb434e81dadcc9f71adf891a3ef5bea8e2b4e
---

diff -up ghostscript-9.07/psi/zbfont.c.cve-2018-19476 ghostscript-9.07/psi/zbfont.c
--- ghostscript-9.07/psi/zbfont.c.cve-2018-19476	2019-01-14 16:06:09.944218434 +0100
+++ ghostscript-9.07/psi/zbfont.c	2019-01-14 16:08:36.868448531 +0100
@@ -618,6 +618,9 @@ sub_font_params(gs_memory_t *mem, const
         return_error(e_invalidfont);
     if (dict_find_string(op, "OrigFont", &porigfont) <= 0)
         porigfont = NULL;
+    if (porigfont != NULL && !r_has_type(porigfont, t_dictionary))
+        return_error(gs_error_typecheck);
+
     if (pomat!= NULL) {
         if (porigfont == NULL ||
             dict_find_string(porigfont, "FontMatrix", &pmatrix) <= 0 ||
@@ -628,8 +631,8 @@ sub_font_params(gs_memory_t *mem, const
     /* Use the FontInfo/OrigFontName key preferrentially (created by MS PSCRIPT driver) */
     if ((dict_find_string((porigfont != NULL ? porigfont : op), "FontInfo", &pfontinfo) > 0) &&
         r_has_type(pfontinfo, t_dictionary) &&
-        (dict_find_string(pfontinfo, "OrigFontName", &pfontname) > 0)) {
-        if ((dict_find_string(pfontinfo, "OrigFontStyle", &pfontstyle) > 0) &&
+        (dict_find_string(pfontinfo, "OrigFontName", &pfontname) > 0) && (r_has_type(pfontname, t_name) || r_has_type(pfontname, t_string))) {
+        if ((dict_find_string(pfontinfo, "OrigFontStyle", &pfontstyle) > 0) && (r_has_type(pfontname, t_name) || r_has_type(pfontname, t_string)) &&
                 r_size(pfontstyle) > 0) {
             const byte *tmpStr1 = pfontname->value.const_bytes;
             const byte *tmpStr2 = pfontstyle->value.const_bytes;
diff -up ghostscript-9.07/psi/zcolor.c.cve-2018-19476 ghostscript-9.07/psi/zcolor.c
--- ghostscript-9.07/psi/zcolor.c.cve-2018-19476	2019-01-14 16:09:23.141891105 +0100
+++ ghostscript-9.07/psi/zcolor.c	2019-01-14 16:27:03.317052840 +0100
@@ -2059,7 +2059,12 @@ static int comparedictkey(i_ctx_t * i_ct
     if (r_type(tempref1) == t_null)
         return 1;
 
-    return comparearrays(i_ctx_p, tempref1, tempref2);
+    code = comparearrays(i_ctx_p, tempref1, tempref2);
+
+    if (code > 0)
+        return 1;
+    else
+        return 0;
 }
 
 /* Check that the WhitePoint of a CIE space is valid */
@@ -5469,6 +5474,9 @@ static int seticcspace(i_ctx_t * i_ctx_p
                 code = dict_find_string(&ICCdict, "N", &tempref);
                 if (code < 0)
                     return code;
+                if (r_type(tempref) != t_integer)
+                    return gs_note_error(gs_error_typecheck);
+
                 components = tempref->value.intval;
                 if (components > count_of(range))
                     return_error(e_rangecheck);
@@ -5684,6 +5692,8 @@ static int iccalternatespace(i_ctx_t * i
     code = dict_find_string(&ICCdict, "N", &tempref);
     if (code <= 0)
         return code;
+    if (!r_has_type(tempref, t_integer))
+        return_error(gs_error_typecheck);
 
     components = tempref->value.intval;
 
@@ -5718,6 +5728,9 @@ static int icccomponents(i_ctx_t * i_ctx
         return code;
 
     code = dict_find_string(&ICCdict, "N", &tempref);
+    if (!r_has_type(tempref, t_integer))
+        return gs_note_error(gs_error_typecheck);
+
     *n = tempref->value.intval;
     return 0;
 }
@@ -5730,6 +5743,9 @@ static int iccdomain(i_ctx_t * i_ctx_p,
     if (code < 0)
         return code;
     code = dict_find_string(&ICCdict, "N", &tempref);
+    if (!r_has_type(tempref, t_integer))
+        return gs_note_error(gs_error_typecheck);
+
     components = tempref->value.intval;
     code = dict_find_string(&ICCdict, "Range", &tempref);
     if (code >= 0 && !r_has_type(tempref, t_null)) {
@@ -5759,6 +5775,8 @@ static int iccrange(i_ctx_t * i_ctx_p, r
     if (code < 0)
         return code;
     code = dict_find_string(&ICCdict, "N", &tempref);
+    if (!r_has_type(tempref, t_integer))
+        return gs_note_error(gs_error_typecheck);
     components = tempref->value.intval;
     code = dict_find_string(&ICCdict, "Range", &tempref);
     if (code >= 0 && !r_has_type(tempref, t_null)) {
diff -up ghostscript-9.07/psi/zcrd.c.cve-2018-19476 ghostscript-9.07/psi/zcrd.c
--- ghostscript-9.07/psi/zcrd.c.cve-2018-19476	2019-01-14 16:30:53.508230767 +0100
+++ ghostscript-9.07/psi/zcrd.c	2019-01-14 16:31:42.609628795 +0100
@@ -222,8 +222,10 @@ zcrd1_params(os_ptr op, gs_cie_render *
         )
         return code;
     if (dict_find_string(op, "RenderTable", &pRT) > 0) {
-        const ref *prte = pRT->value.const_refs;
-
+        const ref *prte;
+ 
+        check_read_type(*pRT, t_array);
+        prte = pRT->value.const_refs;
         /* Finish unpacking and checking the RenderTable parameter. */
         check_type_only(prte[4], t_integer);
         if (!(prte[4].value.intval == 3 || prte[4].value.intval == 4))
diff -up ghostscript-9.07/psi/zfjpx.c.cve-2018-19476 ghostscript-9.07/psi/zfjpx.c
--- ghostscript-9.07/psi/zfjpx.c.cve-2018-19476	2019-01-14 16:32:09.315301395 +0100
+++ ghostscript-9.07/psi/zfjpx.c	2019-01-14 16:32:59.902681210 +0100
@@ -115,6 +115,8 @@ z_jpx_decode(i_ctx_t * i_ctx_p)
                                 dict_find_string(csdict, "N", &nref) > 0) {
                           if_debug1m('w', imemory, "[w] JPX image has an external %"PRIpsint
                                      " channel colorspace\n", nref->value.intval);
+                          if (r_type(nref) != t_integer)
+                              return gs_note_error(gs_error_typecheck);
                           switch (nref->value.intval) {
                             case 1: state.colorspace = gs_jpx_cs_gray;
                                 break;
diff -up ghostscript-9.07/psi/zfont0.c.cve-2018-19476 ghostscript-9.07/psi/zfont0.c
--- ghostscript-9.07/psi/zfont0.c.cve-2018-19476	2019-01-14 16:34:52.816296934 +0100
+++ ghostscript-9.07/psi/zfont0.c	2019-01-14 16:36:07.581380337 +0100
@@ -243,6 +243,9 @@ zbuildfont0(i_ctx_t *i_ctx_p)
         array_get(pfont->memory, &fdepvector, i, &fdep);
         /* The lookup can't fail, because of the pre-check above. */
         dict_find_string(&fdep, "FID", &pfid);
+        if (!r_has_type(pfid, t_fontID))
+            return gs_note_error(gs_error_typecheck);
+
         data.FDepVector[i] = r_ptr(pfid, gs_font);
     }
     pfont->data = data;
diff -up ghostscript-9.07/psi/zfont.c.cve-2018-19476 ghostscript-9.07/psi/zfont.c
--- ghostscript-9.07/psi/zfont.c.cve-2018-19476	2019-01-14 16:33:26.705352619 +0100
+++ ghostscript-9.07/psi/zfont.c	2019-01-14 16:34:29.104587630 +0100
@@ -596,6 +596,9 @@ zfont_info(gs_font *font, const gs_point
         info->members |= FONT_INFO_FULL_NAME;
     if ((members & FONT_INFO_EMBEDDING_RIGHTS)
         && (dict_find_string(pfontinfo, "FSType", &pvalue) > 0)) {
+        if (r_type(pvalue) != t_integer)
+            return gs_note_error(gs_error_typecheck);
+
         info->EmbeddingRights = pvalue->value.intval;
         info->members |= FONT_INFO_EMBEDDING_RIGHTS;
     }
diff -up ghostscript-9.07/psi/zicc.c.cve-2018-19476 ghostscript-9.07/psi/zicc.c
--- ghostscript-9.07/psi/zicc.c.cve-2018-19476	2019-01-14 15:42:17.836379460 +0100
+++ ghostscript-9.07/psi/zicc.c	2019-01-14 15:48:50.612698290 +0100
@@ -79,7 +79,7 @@ int seticc(i_ctx_t * i_ctx_p, int ncomps
         want to have this buffer. */
     /* Check if we have the /Name entry.  This is used to associate with
        specs that have enumerated types to indicate sRGB sGray etc */
-    if (dict_find_string(ICCdict, "Name", &pnameval) > 0){
+    if (dict_find_string(ICCdict, "Name", &pnameval) > 0 && r_has_type(pnameval, t_string)){
         uint size = r_size(pnameval);
         char *str = (char *)gs_alloc_bytes(gs_state_memory(igs), size+1, "seticc");
         memcpy(str, (const char *)pnameval->value.bytes, size);
@@ -261,6 +261,8 @@ zset_outputintent(i_ctx_t * i_ctx_p)
     code = dict_find_string(op, "N", &pnval);
     if (code < 0)
         return code;
+    if (r_type(pnval) != t_integer)
+        return gs_note_error(gs_error_typecheck);
     ncomps = pnval->value.intval;
 
     /* verify the DataSource entry. Creat profile from stream */
diff -up ghostscript-9.07/psi/zimage3.c.cve-2018-19476 ghostscript-9.07/psi/zimage3.c
--- ghostscript-9.07/psi/zimage3.c.cve-2018-19476	2019-01-14 16:36:31.871082554 +0100
+++ ghostscript-9.07/psi/zimage3.c	2019-01-14 16:37:41.626227376 +0100
@@ -53,6 +53,8 @@ zimage3(i_ctx_t *i_ctx_p)
         dict_find_string(op, "MaskDict", &pMaskDict) <= 0
         )
         return_error(e_rangecheck);
+    check_type(*pDataDict, t_dictionary);
+    check_type(*pMaskDict, t_dictionary);
     if ((code = pixel_image_params(i_ctx_p, pDataDict,
                         (gs_pixel_image_t *)&image, &ip_data,
                         12, false, gs_currentcolorspace(igs))) < 0 ||
diff -up ghostscript-9.07/psi/ztrans.c.cve-2018-19476 ghostscript-9.07/psi/ztrans.c
--- ghostscript-9.07/psi/ztrans.c.cve-2018-19476	2019-01-14 16:38:14.893819526 +0100
+++ ghostscript-9.07/psi/ztrans.c	2019-01-14 16:42:22.503788524 +0100
@@ -362,6 +362,7 @@ zimage3x(i_ctx_t *i_ctx_p)
     gs_image3x_t_init(&image, NULL);
     if (dict_find_string(op, "DataDict", &pDataDict) <= 0)
         return_error(e_rangecheck);
+    check_type(*pDataDict, t_dictionary);
     if ((code = pixel_image_params(i_ctx_p, pDataDict,
                    (gs_pixel_image_t *)&image, &ip_data,
                    16, false, gs_currentcolorspace(igs))) < 0 ||
@@ -398,6 +399,9 @@ image_params *pip_data, const char *dict
 
     if (dict_find_string(op, dict_name, &pMaskDict) <= 0)
         return 1;
+    if (!r_has_type(pMaskDict, t_dictionary))
+        return gs_note_error(gs_error_typecheck);
+
     if ((mcode = code = data_image_params(mem, pMaskDict, &pixm->MaskDict,
                                           &ip_mask, false, 1, 16, false, false)) < 0 ||
         (code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0 ||