From: Ken Sharp 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 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 ||