[gs-commits] rev 10590 - trunk/gs/base

ken at ghostscript.com ken at ghostscript.com
Wed Jan 6 11:19:01 UTC 2010


Author: ken
Date: 2010-01-06 11:19:01 +0000 (Wed, 06 Jan 2010)
New Revision: 10590

Modified:
   trunk/gs/base/gsgdata.c
   trunk/gs/base/gstype1.c
   trunk/gs/base/gstype2.c
   trunk/gs/base/gxtype1.c
Log:
Fix bug #691043 "Vulnerability report : Ghostscript gs_type2_interpret null ptr
dereference (Segmentation Fault)". The problem appears to be caused by a corrupt
compressed data stream which results in garbage font data being sent to the type 2 and
under some conditions the type 1, font interpreters.

As noted these font interpreters are normally coded to be intolerant of faults, and
do not normally perform much error checking. As a result badly formed (or as in this
case, garbage) fonts can cause serious problems.

Although the null dereference is the cause of the error, this is actually caused by
interpreting the data as a font, and decrementing the font instruction pointer below
the bottom of the instruction stack. 

The patch here adopts the suggestion from the original bug reporter of checking the
pointer before the dereference, but in addition adds some checking when the
instruction pointer is decremented to see that it does not descend past the bottom of
the stack. This is because tests showed that it was possible to reach this point with
a non-NULL pointer, which was still invalid and caused a segmentation violation.

In addition the free_glyph routine has been modified to check the pgd (pointer to 
glyph data) parameter is non-NULL, and that its 'procs' member is non-NULL, before
attempting to call the free procedure. This fault was exposed by selecting the pdfwrite
device.

Although improved this is not a comprehensive fix, there are other locations where the
font instruction pointer may be incremented past the top, or decremented past the
bottom, of the instruction stack. However the FreeType font interpreter correctly
detects the problems without causing a crash, so I don't think we should expend too
much effort on rewriting our current font code to cope.


Modified: trunk/gs/base/gsgdata.c
===================================================================
--- trunk/gs/base/gsgdata.c	2010-01-05 17:02:09 UTC (rev 10589)
+++ trunk/gs/base/gsgdata.c	2010-01-06 11:19:01 UTC (rev 10590)
@@ -50,7 +50,8 @@
 void
 gs_glyph_data_free(gs_glyph_data_t *pgd, client_name_t cname)
 {
-    pgd->procs->free(pgd, cname);
+    if (pgd != 0 && pgd->procs != 0)
+	pgd->procs->free(pgd, cname);
     gs_glyph_data_from_null(pgd);
 }
 

Modified: trunk/gs/base/gstype1.c
===================================================================
--- trunk/gs/base/gstype1.c	2010-01-05 17:02:09 UTC (rev 10589)
+++ trunk/gs/base/gstype1.c	2010-01-06 11:19:01 UTC (rev 10590)
@@ -161,6 +161,8 @@
 	goto cont;
     ipsp->cs_data = *pgd;
     cip = pgd->bits.data;
+    if (cip == 0)
+	return (gs_note_error(gs_error_invalidfont));
   call:state = crypt_charstring_seed;
     if (encrypted) {
 	int skip = pdata->lenIV;
@@ -170,7 +172,9 @@
 	    decrypt_skip_next(*cip, state);
     }
     goto top;
-  cont:cip = ipsp->ip;
+  cont:if (ipsp < pcis->ipstack || ipsp->ip == 0)
+	return (gs_note_error(gs_error_invalidfont));
+    cip = ipsp->ip;
     state = ipsp->dstate;
   top:for (;;) {
 	uint c0 = *cip++;

Modified: trunk/gs/base/gstype2.c
===================================================================
--- trunk/gs/base/gstype2.c	2010-01-05 17:02:09 UTC (rev 10589)
+++ trunk/gs/base/gstype2.c	2010-01-06 11:19:01 UTC (rev 10590)
@@ -173,6 +173,8 @@
 	goto cont;
     ipsp->cs_data = *pgd;
     cip = pgd->bits.data;
+    if (cip == 0)
+	return (gs_note_error(gs_error_invalidfont));
   call:state = crypt_charstring_seed;
     if (encrypted) {
 	int skip = pdata->lenIV;
@@ -182,7 +184,9 @@
 	    decrypt_skip_next(*cip, state);
     }
     goto top;
-  cont:cip = ipsp->ip;
+  cont:if (ipsp < pcis->ipstack || ipsp->ip == 0)
+	return (gs_note_error(gs_error_invalidfont));
+    cip = ipsp->ip;
     state = ipsp->dstate;
   top:for (;;) {
 	uint c0 = *cip++;

Modified: trunk/gs/base/gxtype1.c
===================================================================
--- trunk/gs/base/gxtype1.c	2010-01-05 17:02:09 UTC (rev 10589)
+++ trunk/gs/base/gxtype1.c	2010-01-06 11:19:01 UTC (rev 10590)
@@ -454,6 +454,8 @@
 	case c_return:
 	    gs_glyph_data_free(&ipsp->cs_data, "gs_type1_piece_codes");
 	    --ipsp;
+	    if (ipsp < ipstack)
+		return (gs_note_error(gs_error_invalidfont));
 	    cip = ipsp->ip, state = ipsp->dstate;
 	    goto top;
 	case cx_hstem:



More information about the gs-commits mailing list