summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2022-09-06 11:29:33 +0100
committerChris Liddell <chris.liddell@artifex.com>2022-09-06 16:58:55 +0100
commita6ed2d417205ddf4194a2385402a5c97fe991013 (patch)
tree4890694f5234945753c0c107d942fbf4904b77f6
parentea03f1a59ba917ca33a7ec72ac69d5aa0a683f50 (diff)
downloadghostpdl-a6ed2d417205ddf4194a2385402a5c97fe991013.tar.gz
graphics library - bounds check type 2 instruction pointer
This is a speculative fix for OSS-fuzz 50448. Despite the fact that we cannot reproduce this, it looks like the problem must stem from reading off the end of the input buffer. This is possible because we do not check the instruction pointer, but just keep on incrementing it until we get an endchar. It looks like we should originally have been doing this, because the ip_state_t structure, which is used to store the state on a stack when we call subroutines, has an 'ip_end' pointer. But we were never using that..... So add code to set and use it, and add a local variable to hold the pointer to the end of the input buffer, and check cip against that.
-rw-r--r--base/gstype2.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/base/gstype2.c b/base/gstype2.c
index 2e7a4ce7e..e6d70f133 100644
--- a/base/gstype2.c
+++ b/base/gstype2.c
@@ -49,6 +49,7 @@
BEGIN\
if ( pcis->init_done < 0 )\
{ ipsp->ip = cip, ipsp->dstate = state;\
+ ipsp->ip_end = endp;\
return type2_sbw(pcis, csp, cstack, ipsp, explicit_width);\
}\
END
@@ -130,7 +131,7 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd,
cs_ptr csp;
#define clear CLEAR_CSTACK(cstack, csp)
ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
- register const byte *cip;
+ register const byte *cip, *endp = NULL;
register crypt_state state;
register int c;
cs_ptr ap;
@@ -176,9 +177,15 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd,
cip = pgd->bits.data;
if (cip == 0)
return (gs_note_error(gs_error_invalidfont));
+ endp = cip + pgd->bits.size;
goto call;
for (;;) {
- uint c0 = *cip++;
+ uint c0;
+
+ if (endp != NULL && cip > endp)
+ return_error(gs_error_invalidfont);
+
+ c0 = *cip++;
charstring_next(c0, state, c, encrypted);
if (c >= c_num1) {
@@ -242,6 +249,7 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd,
cont: if (ipsp < pcis->ipstack || ipsp->ip == 0)
return (gs_note_error(gs_error_invalidfont));
cip = ipsp->ip;
+ endp = ipsp->ip_end;
state = ipsp->dstate;
continue;
case c_undoc15:
@@ -466,6 +474,7 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd,
}
if_debug0m('1', pfont->memory, "\n");
ipsp->ip = cip;
+ ipsp->ip_end = endp;
ipsp->dstate = state;
if (c == c2_cntrmask) {
/****** NYI ******/
@@ -575,8 +584,10 @@ gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd,
}
--csp;
ipsp->ip = cip, ipsp->dstate = state;
+ ipsp->ip_end = endp;
++ipsp;
cip = ipsp->cs_data.bits.data;
+ endp = cip + ipsp->cs_data.bits.size;
call:
state = crypt_charstring_seed;
if (encrypted) {