diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2022-09-06 11:29:33 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2022-09-06 16:58:55 +0100 |
commit | a6ed2d417205ddf4194a2385402a5c97fe991013 (patch) | |
tree | 4890694f5234945753c0c107d942fbf4904b77f6 | |
parent | ea03f1a59ba917ca33a7ec72ac69d5aa0a683f50 (diff) | |
download | ghostpdl-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.c | 15 |
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) { |