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 ||